转自:http://www.dup2.org/node/1096
最近有一个项目,涉及到和别的网站合作,双方通信的鉴权计划是通过 RSA 来做。由于可能涉及到不同的开发环境,于是要研究一下各个语言对 RSA 的支持
openssl 缺省创建出来的公密钥文件是 PEM 格式的,但 Java API 导入密码只能是 DER 格式,特别是密钥必须用 PKCS#8 编码。这就需要对 openssl 产生出来的文件做一下转换
-
- openssl rsa -inform PEM -in rsapriv.pem -outform DER -pubout -out rsapub.der
- openssl pkcs8 -topk8 -inform PEM -in rsapriv.pem -outform DER -nocrypt -out rsapriv.der
- 基础算法的标准是 openssl 的:RSA_private_encrypt/RSA_public_decrypt、RSA_public_encrypt/RSA_private_decrypt 这4个函数,因为 PHP 的 openssl 模块也只提供了这 4 个基础函数(不要幻想用非 openssl 模块之外的东西来做 RSA 运算,比如 PEAR 的 Crypt_RSA,速度慢到令人发指)
- 要注意上述 4 个函数里,可使用的 padding 参数只有那么有限的几种。对应 Java 里面 Cipher.getInstance() 的参数,只能用 "RSA/NONE/PKCS1Padding" 或 "RSA/NONE/NoPadding"(或许 "RSA/None/OAEPPadding" 是对应RSA_PKCS1_OAEP_PADDING,但我没有深究了)。缺省 PHP 里的 padding 是 RSA_PKCS1_PADDING
- 关于 python... 嗯,直接用 ctypes 就好啦
- 用 RSA 签名都是首先将文本做一个单向 hash,然后用私钥将签名加密;校验端拿到签名和文本,用公钥将签名解密,对比是否是文本的 hash。openssl 因此封装了 RSA_sign/RSA_verify 来做这个事情。
- 但 openssl 的几个 NID 哈希算法和标准的sha1/md5好像不太一样,PHP 几乎无法和这两个函数互操作。
- Java API 中 Signature.getInstance() 倒是可以用 "MD2withRSA"、"MD5withRSA" 或 "SHA1withRSA",但也不清楚是否可以和 openssl 的 NID_md2/NID_md2WithRSAEncryption、NID_md5/ NID_md5WithRSAEncryption/NID_md5WithRSA、NID_sha1/NID_sha1WithRSAEncryption/NID_sha1WithRSA 对应起来,仍然需要花时间校验。
总之为了更多语言的互操作能力,我们现在没有用 RSA_sign/RSA_verify 这两个封装好的函数。
本文探讨了不同编程语言对RSA算法的支持,重点介绍了如何将OpenSSL产生的PEM格式密钥转换为DER格式,以及PHP、Java、Python等语言进行RSA加密解密的基本方法。同时,还涉及了使用RSA进行数字签名和验证的过程,并讨论了不同语言之间在哈希算法和RSA密钥封装上的差异。
860

被折叠的 条评论
为什么被折叠?



