SM2-PEM密钥读取写入 - #4
Conversation
rainune
commented
Mar 12, 2022
- 增加 PEM密钥读取与生成PEM密钥,密钥格式兼容OpenSSL.
- 增加了der.py, 参考了 ecdsa.
- 增加了test_sm2_der.py, 对新增功能进行测试.
- encrypt 和 decrypt 的API删除了公私钥的参数,不在需要明文输入,如果确实需要,可以直接赋值。这部分如果不符合软件整体框架的话可以在修改一下。
|
感谢贡献~ PyLint 报错,需要修改下。 SM2的接口感觉还是保持原样比较好,主要是出于兼容性的考虑,目前已经有人在用这个库了,升级之后需要不能break。所以也需要修改下。 |
|
|
||
| # Pyre type checker | ||
| .pyre/ | ||
|
|
| return decrypt(sk, data, self._mode) No newline at end of file | ||
| return decrypt(self._sk, data, self._mode) | ||
|
|
||
| def pk_from_pem(self, pem): |
There was a problem hiding this comment.
我觉得这里弄成这样的两个方法比较直观,当然还要加一些边界检查啥的。之所以把sk和pk暴露在外面,主要是出于防呆的考虑,因为有时候只需要其中的一个key,如果传错了还挺麻烦的,如果方法里边判断抛异常也不太友好。
def load_pem(self, pem, need_sk=False):
if need_sk:
return sm2_pk_from_pem(pem)
else:
return sm2_sk_from_pem(pem)
def dump_pem(self, sk, pk):
if sk:
sm2_pk_to_der(pk)
else:
sm2_sk_to_der(sk, pk)
There was a problem hiding this comment.
按照你的建议,重新设计了一下API:
@classmethod
def load_pem(cls, pem, is_sk = False):
@classmethod
def dump_pem(cls, sk, pk, is_sk = False):
将两个函数设计成classmethod, 分离与SM2类的关系。
加载PEM的时候,需要用户明确该PEM是私钥或公钥;
输出PEM的时候,需要用户明确该次输出是私钥或公钥。函数内部的话,做参数的检查,来看是否满足输出的条件。
这样就不会影响原有的所有API接口,你看是否可行?
There was a problem hiding this comment.
classmethod挺好的。但是感觉is_sk有点奇怪,load_pem在is_sk的情况下,会同时读出来sk和pk,这会不会不符合一般常识。建议改成contains_sk。
dump_pem的is_sk似乎也有点冗余,看起来只有两种情况,同时有sk和pk,以及只有pk,是否不需要传is_sk这个参数呢?直接按下面这个逻辑:
def dump_pem(cls, sk=None, pk=None):
if pk is not None:
if sk is not None:
sm2_sk_to_der(sk, pk)
else:
sm2_pk_to_der(pk)
else:
raise ValueError('Pem must contains pk')
There was a problem hiding this comment.
is_sk的目的是想要用户明确导入的密钥是私钥或者公钥,以便于接下来进行处理.contain_sk好像也没表达出想要的意思,这里是否用pem_type参数代替is_sk?- PEM私钥是同时包含私钥和公钥信息的。嗯...我考虑的是如果只返回私钥,可能会和OpenSSL这样的主流密码库的操作逻辑不太一样,容易引发一些别的误解。这里可以处理为只返回私钥。
- 对于dump_dem函数。 通过
sk是可以推导出pk的,所以,输出私钥PEM的时候是可以只传入sk.
现在有两个思路,
(1)通过*type参数由用户明确PEM或key的类型
@classmethod
def load_pem(cls, pem, pemtype = 'pk'):
...
return key #只返回一个key,sk 或 pk
@classmethod
def dump_pem(cls, key, keytype = 'pk'):
(2)当然,如果彻底去掉参数 *type也是可以的,可以在函数内部进行判断。私钥公钥及其PEM都是比较好区分的。
@classmethod
def load_pem(cls, pem):
...
return key #只返回一个key,sk 或 pk
@classmethod
def dump_pem(cls, key):
但是第二种方法感觉有点奇怪 😄 我等讨论完API,再去修改一下代码...
| openssl ecparam -genkey -name SM2 -out sk.pem | ||
| openssl ec -in sk.pem -pubout -out pk.pem | ||
| ''' | ||
| with open('sk.pem') as f: |
There was a problem hiding this comment.
这里能否考虑动态生成pem呢?另外请确认下这个pem里面是否包含您个人或单位的信息。