发布网友 发布时间:2022-04-26 13:45
共2个回答
热心网友 时间:2022-04-26 14:37
之前在项目上用到AES256加密解密算法,刚开始在java端加密解密都没有问题,在iOS端加密解密也没有问题。但是奇怪的是在java端加密后的文件在iOS端无法正确解密打开,然后简单测试了一下,发现在java端和iOS端采用相同明文,相同密钥加密后的密文不一样!上网查了资料后发现iOS中AES加密算法采用的填充是PKCS7Padding,而java不支持PKCS7Padding,只支持PKCS5Padding。我们知道加密算法由算法+模式+填充组成,所以这两者不同的填充算法导致相同明文相同密钥加密后出现密文不一致的情况。那么我们需要在java中用PKCS7Padding来填充,这样就可以和iOS端填充算法一致了。要实现在java端用PKCS7Padding填充,需要用到bouncycastle组件来实现,下面我会提供该包的下载。啰嗦了一大堆,下面是一个简单的测试,上代码!001packagecom.encrypt.file;002003004importjava.io.UnsupportedEncodingException;005importjava.security.Key;006importjava.security.Security;007008importjavax.crypto.Cipher;009importjavax.crypto.SecretKey;010importjavax.crypto.spec.SecretKeySpec;011012publicclassAES256Encryption{013014/**015*密钥算法016*java6支持56位密钥,bouncycastle支持64位017**/018publicstaticfinalStringKEY_ALGORITHM="AES";019020/**021*加密/解密算法/工作模式/填充方式022*023*JAVA6支持PKCS5PADDING填充方式024*Bouncycastle支持PKCS7Padding填充方式025**/026publicstaticfinalStringCIPHER_ALGORITHM="AES/ECB/PKCS7Padding";027028/**029*030*生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥031*@returnbyte[]二进制密钥032**/033publicstaticbyte[]initkey()throwsException{034035////实例化密钥生成器036//Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());037//KeyGeneratorkg=KeyGenerator.getInstance(KEY_ALGORITHM,"BC");038////初始化密钥生成器,AES要求密钥长度为128位、192位、256位039////kg.init(256);040//kg.init(128);041////生成密钥042//SecretKeysecretKey=kg.generateKey();043////获取二进制密钥编码形式044//returnsecretKey.getEncoded();045//为了便于测试,这里我把key写死了,如果大家需要自动生成,可用上面注释掉的代码046returnnewbyte[]{0x08,0x08,0x04,0x0b,0x02,0x0f,0x0b,0x0c,0470x01,0x03,0x09,0x07,0x0c,0x03,0x07,0x0a,0x04,0x0f,0480x06,0x0f,0x0e,0x09,0x05,0x01,0x0a,0x0a,0x01,0x09,0490x06,0x07,0x09,0x0d};050}051052/**053*转换密钥054*@paramkey二进制密钥055*@returnKey密钥056**/057publicstaticKeytoKey(byte[]key)throwsException{058//实例化DES密钥059//生成密钥060SecretKeysecretKey=newSecretKeySpec(key,KEY_ALGORITHM);061returnsecretKey;062}063064/**065*加密数据066*@paramdata待加密数据067*@paramkey密钥068*@returnbyte[]加密后的数据069**/070publicstaticbyte[]encrypt(byte[]data,byte[]key)throwsException{071//还原密钥072Keyk=toKey(key);073/**074*实例化075*使用PKCS7PADDING填充方式,按如下方式实现,就是调用bouncycastle组件实现076*Cipher.getInstance(CIPHER_ALGORITHM,"BC")077*/078Security.addProvider(neworg.bouncycastle.jce.provider.BouncyCastleProvider());079Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM,"BC");080//初始化,设置为加密模式081cipher.init(Cipher.ENCRYPT_MODE,k);082//执行操作083returncipher.doFinal(data);084}085/**086*解密数据087*@paramdata待解密数据088*@paramkey密钥089*@returnbyte[]解密后的数据090**/091publicstaticbyte[]decrypt(byte[]data,byte[]key)throwsException{092//欢迎密钥093Keyk=toKey(key);094/**095*实例化096*使用PKCS7PADDING填充方式,按如下方式实现,就是调用bouncycastle组件实现097*Cipher.getInstance(CIPHER_ALGORITHM,"BC")098*/099Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM);100//初始化,设置为解密模式101cipher.init(Cipher.DECRYPT_MODE,k);102//执行操作103returncipher.doFinal(data);104}105/**106*@paramargs107*@throwsUnsupportedEncodingException108*@throwsException109*/110publicstaticvoidmain(String[]args)throwsUnsupportedEncodingException{111112Stringstr="AES";113System.out.println("原文:"+str);114115//初始化密钥116byte[]key;117try{118key=AES256Encryption.initkey();119System.out.print("密钥:");120for(inti=0;i热心网友 时间:2022-04-26 17:29
你的这个16字节向量是想做IV?那我认为手动输入这个比较好,随机产生的这个IV值并不会增加你的加密强度,你可以看看《密码导论》里面好像有这个的证明。