
一个对象能被称为 hashable , 它必须有个 hash 值,这个值在整个生命周期都不会变化,而且必须可以进行相等比较,所以一个对象可哈希,它必须实现__hash__() 与 __eq__() 方法。
Python 的某些链接库在内部需要使用hash值,例如往集合中添加对象时会用__hash__() 方法来获取hash值,看它是否与集合中现有对象的hash值相同,如果相同则会舍去不加入,如果不同,则使用__eq__() 方法比较是否相等,以确定是否需要加入其中。
对于 Python 的内建类型来说,只要是创建之后无法修改的(immutable)类型都是 hashable 如字符串,可变动的都是 unhashable的比如:列表、字典、集合, 他们在改变值的同时却没有改变id,无法由地址定位值的唯一性,因而无法哈希 。我们自定义的类的实例对象默认也是可哈希的(hashable),而hash值也就是它们的id()。
P1签名:即裸签名,签名值中只有签名信息
p7签名:即,签名中可以带有其他的附加信息,例如签名证书信息,签名原文信息,时间戳信息等
所以要注意,不要p7的签名,用p1的方式来验签,这样是不对的是错误的
1对要签名的信息,用指定的hash算法,获取信息的hash值
2用私钥,对hash值进行加密,输出加密串(也就是签名值)
以上方式也就是裸签名,PKCS#1
1对要签名的信息(也就是签名原文),用指定的hash算法,获取信息的hash值
2用公钥信息,解密签名值,从中获取加密的hash串,和上面获取的hash值进行对比,一致则认为验签通过,不一致则不通过
需要注意,如果调用远程签名(比如电子签名),因为根据要签名的数据格式的不同,所以我们本地验签的时候,也要根据不同的签名方式,来进行验证(也就说,他们那边签名的时候,真正用来签名的字节数组是怎么来的)
目前常见的几种方式:(P1签名验签)
CT_HASH:告诉签名方,我这个是对签名原文hash过了的hash串,你们直接对这个值进行加密即可,不需要再hash了
所以这种方式,我们本地验签的时候,要将原文放入进行验签,而不是hash过后的hash值(因为验签的时候,它又会hash一次)
CT_MESSAGE:即,告诉签名方,我发过去的内容,就是签名的原文一般来说,因为签名值都是字节数组,所以签名方会根据约定的编码方式,对这个签名原文按规定的编码方式,取它的字节数组之后,进行签名
我们本地验签的时候,也要对原文做同样的 *** 作
CT_BASE64_DATA:因为有时候,我们要签名的原文,它就是一个byte[],但是为了方便传输,一般签名方都要求接受的是一个字符串所以就有了这种签名方式即:我们需要对签名原文的byte[]做base64编码,签名方收到之后,再做解码,并且把解码后的byte[]进行签名
所以我们本身验签的时候,只要传入byte[]就行
第三方返回的签名值,一般也是签名值byte[]做base64编码后的字符串,所以我们要做base64解码,才能获取到签名值byte[]
P7签名其实也就是P1签名的基础上,附加一些其他的信息(因为P1是裸签名,只有加密串,除了本人自己,根本不知道签名证书,公钥,签名算法,签名用的hash算法,时间戳,签名原文等等信息是什么,不便于验证签名,所以就需要有P7签名作为补充,其实也就是在P1之后,在加密串的基础上,附加这些信息上去)
所以我们在itextpdf的源码上能看到,其实它做签名的时候,也就是先构建出一个要签名的字符串,然后丢给某个私钥进行签名,获得签名值,它再对这个签名值附加:证书链,时间戳等等信息,然后构建出一个P7签名,然后放入PDF文件中
PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封[22]。
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码 *** 作,就可以将加密的消息转换成PEM消息[26]。
以上就是关于可哈希(hashable)与不可哈希(unhashable)全部的内容,包括:可哈希(hashable)与不可哈希(unhashable)、p1和p7签名的区别、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)