每一個(gè)寫接口的人都是天使性誉,后來對(duì)接的時(shí)候折翼了羽氮。 ---心疼自己
好幾天沒有繼續(xù)更新,主要是被卡在了對(duì)接上秽誊,已經(jīng)全部調(diào)通鲸沮,代碼還是經(jīng)得起考驗(yàn)的。
這次主要是關(guān)于AES加密的部分锅论,做的一些代碼實(shí)現(xiàn)讼溺,并可以和IOS,安卓端完美對(duì)接最易。
加解密的算法注入方式采用:AES/CBC/PKCS7Padding
測(cè)試了多種注入:NoPadding PKCS5Padding PKCS7Padding 等怒坯,但是在聯(lián)調(diào)時(shí)出現(xiàn)以下問題:
1.IOS只能夠使用NoPadding 和 PKCS7Padding 的方式注入,java端可以使用PKCS5Padding(JDK) 或者PKCS7Padding(BC)的方式接受藻懒。
2.安卓端代碼和java后端代碼類似剔猿,所有 使用相同的注入方式是是通的,PKCS5Padding(來自JDK) 和PKCS7Padding(來自BC)嬉荆。NoPadding 未做測(cè)試归敬。
3.關(guān)于傳說中的Linux下安卓端加密由于key生成的方式不同,會(huì)在后臺(tái)解密出現(xiàn)亂碼情況鄙早。KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128,new SecureRandom());親測(cè)可用汪茧。
4.加解密的時(shí)候設(shè)置偏移量,原因IOS端將偏移量設(shè)置為null會(huì)出現(xiàn)限番,解密失敳瘴邸(我不清楚IOS到底有沒有不需要偏移量的函數(shù)),解決方案安卓IOS后臺(tái)使用相同的偏移量設(shè)置就OK了弥虐。
↓↓↓↓↓↓上代碼:
package aes;
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* AES安全編碼組件
* @author zhaofh 2016-07-06
* @version 1.0
* @since 1.0
*/
public abstract class AESUtil extends BaseCoder {
/**
* ALGORITHM 算法 <br>
* AES key size must be equal to 128, 192 or 256,but 192 and 256 bits may not be available
*/
public static final String ALGORITHM = "AES";
private static String ivParameter = "0102030405060708";//偏移量,可自行修改
/**
* 轉(zhuǎn)換密鑰<br>
*
* @param key
* @return
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception {
SecretKey secretKey = new SecretKeySpec(key, ALGORITHM);
return secretKey;
}
/**
* 解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] data, String key) throws Exception {
Key k = toKey(AESUtil.decryptBASE64(key));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding",new BouncyCastleProvider());
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
cipher.init(Cipher.DECRYPT_MODE, k,iv);
return cipher.doFinal(data);
}
/**
* 加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] data, String key) throws Exception {
Key k = toKey(decryptBASE64(key));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding",new BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, k,iv);
return cipher.doFinal(data);
}
/**
* 生成密鑰
*
* @return
* @throws Exception
*/
public static String initKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
kg.init(128,random);
//kg.init(128,new SecureRandom());↑↑↑↑↑↑↑↑上兩行代碼可換成這個(gè)
SecretKey secretKey = kg.generateKey();
return encryptBASE64(secretKey.getEncoded());
}
}
測(cè)試類:
package aes;
import ywsoftware.AESCoder;
/**
* @author zhaofh 2016年7月29日
*
*/
public class AESTest {
public static void main(String[] args) throws Exception {
String inputStr = "AES";
String key = AESCoder.initKey();
System.err.println("原文:\t" + inputStr);
System.err.println("密鑰:\t" + key);
byte[] inputData = inputStr.getBytes();
inputData = AESCoder.encrypt(inputData, key);
System.err.println("加密后:\t" + AESCoder.encryptBASE64(inputData));
byte[] outputData = AESCoder.decrypt(inputData, key);
String outputStr = new String(outputData);
System.err.println("解密后:\t" + outputStr);
}
}
BaseCode代碼戳這里→→→→BaseCode代碼
最終選取IOS使用自帶的PKCS7Padding方式注入扩灯。
以上代碼安卓和JAVA通用。
IOS的AES加密代碼←←←←IOS的AES加密代碼戳這里
下一節(jié)講下霜瘪,關(guān)于加密珠插,JDK BC CC的實(shí)現(xiàn),以Base64為例貼出代碼粥庄。