這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
由於Java AES256 加密庫受出口限制,所以只採用AES 128加密。
互連要達到的要求
- 加密位元:統一采AES 128
- 區塊編碼器條件:CBC/PKCS#5PADDING
- 密鑰填充方式一樣
因為android的預設填充與java預設不一樣,而且在不同的JDK版本裡也會出現key填充不一致的情況,所以自己手動填充,Go也採取與java一樣的填充方式:不滿16位補零。AES兩個平台均要實現AES的加密與解密操作。加密結果轉成base64。
關鍵代碼如下所示:
go:
//填充func paddingkey(key string) (string){ var buffer bytes.Buffer buffer.WriteString(key) for i:=len(key);i<16;i++{ buffer.WriteString("0") } return buffer.String()}//加密func En(src string,srckey string)(string){ key := []byte(paddingkey(srckey)) result, err := AesEncrypt([]byte(src), key) if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(result)}//解密func UnEn(src string,srckey string)(string) { key := []byte(paddingkey(srckey)) var result []byte var err error result,err=base64.StdEncoding.DecodeString(src) if err != nil { panic(err) } origData, err := AesDecrypt(result, key) if err != nil { panic(err) } return string(origData)}func AesEncrypt(origData, key []byte,IV []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() origData = PKCS5Padding(origData, blockSize) // origData = ZeroPadding(origData, block.BlockSize()) blockMode := cipher.NewCBCEncrypter(block, IV[:blockSize]) crypted := make([]byte, len(origData)) // 根據CryptBlocks方法的說明,如下方式初始化crypted也可以 // crypted := origData blockMode.CryptBlocks(crypted, origData) return crypted, nil}func AesDecrypt(crypted, key []byte,IV []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } blockSize := block.BlockSize() blockMode := cipher.NewCBCDecrypter(block,IV[:blockSize]) origData := make([]byte, len(crypted)) // origData := crypted blockMode.CryptBlocks(origData, crypted) origData = PKCS5UnPadding(origData) // origData = ZeroUnPadding(origData) return origData, nil}func PKCS5Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...)}func PKCS5UnPadding(origData []byte) []byte { length := len(origData) // 去掉最後一個位元組 unpadding 次 unpadding := int(origData[length-1]) return origData[:(length - unpadding)]}
java:
public class AEStool { private IvParameterSpec ivSpec; private SecretKeySpec keySpec; public AEStool(String srckey) { String key=paddingkey(srckey); try { byte[] keyBytes = key.getBytes(); byte[] buf = new byte[16]; for (int i = 0; i < keyBytes.length && i < buf.length; i++) { buf[i] = keyBytes[i]; } this.keySpec = new SecretKeySpec(buf, "AES"); this.ivSpec = new IvParameterSpec(keyBytes); } catch (Exception e) { e.printStackTrace(); } } public String encrypt(String src) { try { byte[] origData=src.getBytes(); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, this.keySpec, this.ivSpec); byte[] re= cipher.doFinal(origData); return Base64.encodeToString(re,Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return null; } public String decrypt(String src) throws Exception { byte[] crypted=Base64.decode(src,Base64.DEFAULT); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, this.keySpec, this.ivSpec); byte re[] =cipher.doFinal(crypted); return new String(re); } private static String paddingkey(String liu) { StringBuffer sb=new StringBuffer(liu); for(int i=liu.length();i<16;i++) { sb.append("0"); } return sb.toString(); }}