使用golang实现AES算法很简单,系统库中已自带了CBC、CFB等等许多加密模式,而且可以很方便的设置IVPara,但是前几日在做AES加密时,发现传入的key必须是128bit、192bit或256bit,记得当时用Java实现的时候并没有这个问题。AES中的key的确是必须满足以上要求才行。这里就涉及到PKCS5Padding的
/** * AES 加密 * * @param data 明文 * @param password 生成秘钥的关键字 * @return */ public static byte[] encrypt(byte[] data,String password) { try { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes()); SecretKeySpec key = new SecretKeySpec(password.getBytes(CharsetMap.charset_utf8),"AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE,key,zeroIv); byte[] encryptedData = cipher.doFinal(data); return encryptedData; // return byte2HexStr(encryptedData); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } return null; }
可见Ciper初始化的时候,加入了PKCS5Padding特性,所以会对输入的key进行一次包装,避免了开发者的手动处理。
所以在golang中,需要自行实现该功能:
//加密数据 func (a *AesCryptor) Encrypt(data []byte) ([]byte,error) { aesBlockEncrypter,err := aes.NewCipher(a.key) content := PKCS5Padding(data,aesBlockEncrypter.BlockSize()) encrypted := make([]byte,len(content)) if err != nil { println(err.Error()) return nil,err } aesEncrypter := cipher.NewCBCEncrypter(aesBlockEncrypter,a.iv) aesEncrypter.CryptBlocks(encrypted,content) return encrypted,nil } //解密数据 func (a *AesCryptor) Decrypt(src []byte) (data []byte,err error) { decrypted := make([]byte,len(src)) var aesBlockDecrypter cipher.Block aesBlockDecrypter,err = aes.NewCipher(a.key) if err != nil { println(err.Error()) return nil,err } aesDecrypter := cipher.NewCBCDecrypter(aesBlockDecrypter,a.iv) aesDecrypter.CryptBlocks(decrypted,src) return PKCS5Trimming(decrypted),nil } /** PKCS5包装 */ func PKCS5Padding(cipherText []byte,blockSize int) []byte { padding := blockSize - len(cipherText)%blockSize padText := bytes.Repeat([]byte{byte(padding)},padding) return append(cipherText,padText...) } /* 解包装 */ func PKCS5Trimming(encrypt []byte) []byte { padding := encrypt[len(encrypt)-1] return encrypt[:len(encrypt)-int(padding)] }注:以上代码部分来源于互联网。