Golang實現AES/CBC/PKCS5Padding演算法
阿新 • • 發佈:2019-02-11
使用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)] }