RSA在Android、vc、java下加解密实现互通。

最近公司项目需求要对上传/下载的数据进行AES+RSA的加解密需求,客户有vc的RSA加解密接口,而且说要与他们的系统兼容,也就是说vc下要用他们的模块实现加解密。期间过程有几个坑,原因都是自己的对这些加密的协议/准则/规范不熟,以此文记录备案。

坑1:

首先先是百度java的RSAUtils,网上很多现成的,例如这个:http://www.2cto.com/kf/201408/328112.html,公钥使用X509的解析类,私钥使用PKCS#8的解析类。编写测试程序一切正常。。。

然后就是调试客户提供的vc模块,测试程序如下图

然后走到RSA_EnCrypt的时候就出现错误,缺出现了0xC0000005未知性错误。(绝对不是输出没分配内存or内存不足-_-!!)这下就有点难搞了,打电话咨询对方,对方就说要遵循openssl标准生成的key哦~然后我汗颜了回他说,我是用你demo生成的key放进去接口用得,还会报错?然后对方也鄙视我了一下说,你发你的测试程序来看看。

发过去半个小时后,对方就返回一个截图给我

然后还说:上面的截图的做法没错,只是如果你传密匙或私匙字符串参数的时候,需要保持格式分割,如在VC里面你可以在每行后面加个\n,如果读入整个文本即保持了每行后面有\r\n就可以了,这个是标准pem格式的要求,事实上如果直接用openssl命令行生成密匙对并保存为文本,它也是用\n来分割的,直接文本打开是看不到回车换行的。

嗯,以上这句话就是坑1结论,上面说的:用传统的记事本打开用openssl生成的pem确实没了\n的格式,就一行串的写过去,而且可能是java的工具类内部已经处理这种一行串字符串格式的key,实际应用硬编码或者测试的时候会对我这种小白造成第一印象错误,而openssl的接口需要保持这种文本格式才能解析成功。还有,那个begin和end也是需要写进去的!!!

坑2

好了,既然java有工具类了,vc有接口了,那就是实现互相加解密吧~先是vc用public加密,java用privatekey解密,恩恩。

然而实践中中是有各种不知为何,而知后也不过如此的错误。首先声明一点就是,加密后的内容全球99.99%的人都是用base64将其编码,解密前需先将其这串内容用base64解码还原,嗯嗯。使用客户方提供的demo生成的公私密钥对,vc加密后把加密内容的传给java平台,然后java使用privatekey解密,遗憾的是java解码失败,出错的原因居然是privatekey解析不成功,这下又摸不着头脑了,不是说都按openssl的标准吗?sun公司不会另起标准的吧?

混乱了一阵子,仔细查看log是pkcs8的编码出错了,然后又百度pkcs8为何物,直叫我生死相许~.~

http://bbs.csdn.net/topics/190044123  <--- 这链接就详细说明了这些密钥的分类划分,然后看见到pkcs系列的介绍,然后还有http://blog.csdn.net/jdsjlzx/article/details/41441147这兄弟说的:密钥就基本生成,不过这样密钥对的私钥是无法在代码中直接使用的,要想使用它需要借助RSAPrivateKeyStructure这个类,java是不自带的。所以为了方便使用,我们需要对私钥进行PKCS#8编码!!!

然后一个猜测出现在我的脑海里,我的梦里,我的心里,我的记录里。。。难不成vc的不是按照pkcs#8的?打电话给客户方,得到答复是:不是pkcs#8,但不记得是pkcs#12还是什么的。=_=

好吧,再看看pkcs#12是何方神圣,链接我就不附带了。蛋疼的是,pkcs#12是证书的协议而且带密码的啊,你就一个密钥字符串,这是哪跟哪呢?

再一次在混乱的思维中冷静下来,客户方一直说遵从openssl标准,vc的openssl我不是没用过,最原始的java不能使用的pem文件是什么格式?经百度是pkcs#1,嗯哼!?这里有玄机,立刻再搜索有没工具把pkcs#1的变pkcs#8的,http://tool.chacuo.net/cryptrsapkcs1pkcs8 <-这网址就是把pkcs#1的私钥转成pkcs#8的格式,好吧,再次利用vc的demo生成公私密钥对(假设是pkcs#1),然后提取私钥利用工具生成一串pkcs#8格式的密钥。放进去java测试,解密成功!

总结下坑2:java现有的工具都是x509-pkcs#8的公私密钥对,而vc利用openssl的就很原始很开放的,就怪双方没有沟通好,造成坑2一系列的麻烦。

坑3,android的rsa隐坑=_=

按道理,java的系统jar包能在android上找到,那为啥java平台的rsa加解密能与vc互通,android就失败?android加密的内容送到java/vc里解密是一段空串?还有一点奇怪的是,java/vc的rsa加密后的内容都是随机不一样的,为啥android的加密后的内容那串字符串居然是一样的呢?搜索如下文章http://blog.csdn.net/yanzi1225627/article/details/26508035 和 http://blog.csdn.net/anod/article/details/8734608最后就是这个http://my.oschina.net/cwalet/blog/35867,还有这个http://juliusdavies.ca/commons-ssl/pkcs8.html(<-需要FQ) 慢慢的理解到android的虚拟机与windows上的虚拟机还真不一样。

android自带的只包含一个 默认的 RSA的最标准算法 是没填充“RSA/ECB/NoPadding”
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
所以android的每次运行都一样
然后这个Cipher里提供了第二个参数给你更换算法提供者
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",new org.bouncycastle.jce.provider.BouncyCastleProvider());
这个就是按PKCS1填充的然后每次都不一样。这就是区别。

坑3结论:无话可说。从得到需求和客户方沟通到三平台互通用时4天。

时间: 2024-10-20 08:20:16

RSA在Android、vc、java下加解密实现互通。的相关文章

CryptoJS和Java进行加解密

使用AES加密算法时CryptoJS无法对Java的十六进制的AES的字符串的密文进行解密的问题. 在使用CryptoJS进行前后端加密时.使用CryptoJS对java的16进制的aes的字符串密文进行解密遇到无法进行解密.在测试过程中我对同一个消息进行加密,获得了同样的密文.在这种情况下CryptoJS不能Java进行解密时不可能的.在思考了几分钟,我对CryptoJS加解密对象进行查看它们的原型.它们都属于object,在仔细查看中,发现他们的属性和使用CryptoJS.enc.Hex.p

java des加解密

package com.des.test; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.cr

两种JavaScript的AES加密方式(可与Java相互加解密)

由于JavaScript属于弱类型脚本语言,因此当其与强类型的后台语言进行数据交互时会产生各种问题,特别是加解密的操作.本人由于工作中遇到用js与Java进行相互加解密的问题,在网上查了很多资料及代码段,均无法解决.后总结多篇文档内容终于找到解决办法,现记录与此: 第一种:加解密时需要秘钥(key)和秘钥偏移量(iv)的情况,在线验证地址:http://www.seacha.com/tools/aes.html //该方法可与Java进行相互加解密 <!doctype html> <ht

C# AESCBC256 与 java AESCBC256 加解密

和某上市公司对接接口,他们试用 java AES CBC PKCS5 256 加解密.网上C# 基本不合适. 注意:C# PKCS7 对应 java PKCS5 /// <summary> /// AES加密 /// </summary> /// <param name="encryptStr">明文</param> /// <param name="key">密钥</param> /// &l

python实现RSA加密和签名以及分段加解密的方案

python实现RSA加解密和签名加解签 1.生成秘钥对 在这边为了方面演示,手动生成一个密钥对(项目中的秘钥对由开发来生成,会直接给到我们) 生成秘钥对的时候,可以指定生成秘钥的长度,一般推荐使用1024bit, 1024bit的rsa公钥,加密数据时,最多只能加密117byte的数据),数据量超过这个数,则需要对数据进行分段加密,但是目前1024bit长度的秘钥已经被证明了不够安全,尽量使用2048bit长度的秘钥.2048bit长度的秘钥,最多245byte长度的数据 计算公式如下: 秘钥

java 对称加解密

对称加密 1.特点 加密密钥与解密密钥相同 2.分类 2.1 DES 2.2 3DES 2.3 AES 2.4 PBE 3.各种加密示例 3.1 DES import java.security.Key; import java.security.Security; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.Sec

JAVA Aes加解密详解

上篇随笔留了一个问题,两种加密结果不一样? 其实是内部实现方式不一样,具体见注释 1 /** 2 * 提供密钥和向量进行加密 3 * 4 * @param sSrc 5 * @param key 6 * @param iv 7 * @return 8 * @throws Exception 9 */ 10 public static String Encrypt(String sSrc, byte[] key, byte[] iv) throws Exception { 11 SecretKey

Java DES 加解密(&quot;DES/CBC/PKCS5Padding&quot;)

/** * DES加密 * * @param data 加密数据 * @param key 密钥 * @return 返回加密后的数据 */ public static byte[] desEncrypt(byte[] data, String key, String charset) { try { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); byte[] k = charset == null || cha

Java DESede 加解密(&quot;DESede/ECB/PKCS5Padding&quot;)

private static final Cipher DES_CIPHER; static { try { DES_CIPHER = Cipher.getInstance("DESede/ECB/PKCS5Padding"); } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { throw Throwables.propagate(e); } } public static String encryptDES