我编写了一个简单的Python脚本,它使用我的智能卡(Rutoken ECP SC)、PKCS#11库(由我的供应商实现)和PyKCS11 Python包装器进行数字签名。 我已经用这张卡生成了私钥/公钥对,并用pkcs11创建了一个签名,但我不知道如何验证这个签名数据。 但我不知道如何在pks11++库中实现这个问题。如果有人能告诉我如何解决这个问题,我将不胜感激。在
这是我的剧本:
import PyKCS11
import getopt
import sys
import platform
red = blue = magenta = normal = ""
if sys.stdout.isatty() and platform.system().lower() != 'windows':
red = "\x1b[01;31m"
blue = "\x1b[34m"
magenta = "\x1b[35m"
normal = "\x1b[0m"
format_long = magenta + " %s:" + blue + " %s (%s)" + normal
format_binary = magenta + " %s:" + blue + " %d bytes" + normal
format_normal = magenta + " %s:" + blue + " %s" + normal
pkcs11 = PyKCS11.PyKCS11Lib()
lib_path = "/usr/lib/pkcs11-arm/rtpkcs11ecp/librtpkcs11ecp.so"
pkcs11.load(lib_path)
info = pkcs11.getInfo()
print "Library manufacturerID: " + info.manufacturerID
slots = pkcs11.getSlotList()
print "Available Slots:", len(slots)
# As I understand we need only first slot
if len(slots) > 0:
slot = slots[0]
slotInfo = pkcs11.getSlotInfo(slot)
tokenInfo = pkcs11.getTokenInfo(slot)
flags = PyKCS11.CKF_RW_SESSION
session = pkcs11.openSession(slot, flags)
print "Opened session 0x%08X" % session.session.value()
pin = "12345678"
session.login(pin)
objects = session.findObjects()
all_attributes = PyKCS11.CKA.keys() # all keys supported by SC
print "Defining KEY_GENERATION mechanism"
mech = PyKCS11.Mechanism(PyKCS11.CKM_RSA_PKCS_KEY_PAIR_GEN, None)
print "Generating key"
public_template = [
(PyKCS11.CKA_CLASS, PyKCS11.CKO_PUBLIC_KEY),
(PyKCS11.CKA_PRIVATE, PyKCS11.CK_FALSE),
(PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
(PyKCS11.CKA_ENCRYPT, PyKCS11.CK_TRUE),
(PyKCS11.CKA_VERIFY, PyKCS11.CK_TRUE),
(PyKCS11.CKA_WRAP, PyKCS11.CK_TRUE),
(PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_RSA),
(PyKCS11.CKA_VERIFY_RECOVER, PyKCS11.CK_TRUE),
(PyKCS11.CKA_MODULUS_BITS, 2048),
]
private_template = [
(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY),
(PyKCS11.CKA_PRIVATE, PyKCS11.CK_TRUE),
(PyKCS11.CKA_TOKEN, PyKCS11.CK_TRUE),
(PyKCS11.CKA_DECRYPT, PyKCS11.CK_TRUE),
(PyKCS11.CKA_SIGN, PyKCS11.CK_TRUE),
(PyKCS11.CKA_UNWRAP, PyKCS11.CK_TRUE)
]
(pub, priv) = session.generateKeyPair(public_template, private_template, mech)
# ==================================================
# Signing data
sourceText = "Hello World"
binaryData = ' '.join(format(ord(x), 'b') for x in sourceText)
signMechanism = PyKCS11.Mechanism(PyKCS11.CKM_RSA_PKCS, None)
signedData = session.sign(priv, binaryData, signMechanism)
print signedData
#====================================================
# now we have to verify signedData using the private key
session.logout()
session.closeSession()
print "Close session 0x%08X" % session.session.value()
这是sign方法的输出:
^{pr2}$
此代码适用于我(注意,公共指数假定为3字节长):
我不喜欢python,所以请把它当作概念的证明,而不是解决方案。有趣的部分:
由于您的PKCS#11驱动程序不支持带有散列的RSA签名,因此需要计算散列并手动构建DigestInfo ASN.1 part(结果在
binaryData2
变量中)由于
RSA.new_pub_key()
为BN_mpi2bn接受一个openssl格式的元组(它在内部使用),所以需要在模数前面加上一个额外的\x00
前缀,以确保它被解释为正数('\x00\x00\x01\x01\x00'
部分)给定函数
verify()
使用openssl的RSA_verify,该函数将签名数据的摘要(而不是数据本身)作为参数,它需要遵守并给它摘要(从签名生成部分重用,如果计划使用单独的verify函数,则必须生成新的摘要)注意:对于SHA256,您需要使用适当的digestInfo magic ASN.1字符串前缀(有关可用值,请参见here)+来自hashlib的适当摘要对象+正确的第三个verify调用参数。在
祝你好运!在
相关问题 更多 >
编程相关推荐