文章首发于:clawhub.club
重要:
在Java中不带模式和填充来获取AES算法的时候,其默认使用AES/ECB/PKCS5Padding!!!
1 Java的AES加解密
如果把Cipher.getInstance(“AES”);中的”AES”换成”AES/ECB/PKCS5Padding”,效果是一样的。
1.1 加密操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | 
 
 
 
 
 
 
    public static byte[] encrypt(byte[] data, byte[] key)           throws Exception {       Key secretKey = new SecretKeySpec(key, "AES");       Cipher cipher = Cipher.getInstance("AES");       cipher.init(Cipher.ENCRYPT_MODE, secretKey);       return cipher.doFinal(data);   }
 
  | 
 
1.2 解密操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | 
 
 
 
 
 
 
  public static byte[] decrypt(byte[] data, byte[] key)         throws Exception {     Key secretKey = new SecretKeySpec(key, "AES");     Cipher cipher = Cipher.getInstance("AES");     cipher.init(Cipher.DECRYPT_MODE, secretKey);     return cipher.doFinal(data); }
 
  | 
 
2 Golang的AES加解密
Golang中是没有现成的ECB/PKCS5Padding填充算法的,需要自己写或找份。
2.1 加密操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   |  func AESEncrypt(src, key []byte) []byte { 	block, err := aes.NewCipher(key) 	if err != nil { 		log.Logger.Error("txn put fail: %v", err) 		return nil 	} 	ecb := NewECBEncrypter(block) 	content := []byte(src) 	content = PKCS5Padding(content, block.BlockSize()) 	des := make([]byte, len(content)) 	ecb.CryptBlocks(des, content) 	return des }
 
  | 
 
2.2 解密操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   |  func AesDecrypt(crypted, key []byte) []byte { 	block, err := aes.NewCipher(key) 	if err != nil { 		log.Logger.Error("txn get fail: %v", err) 		return nil 	} 	blockMode := NewECBDecrypter(block) 	origData := make([]byte, len(crypted)) 	blockMode.CryptBlocks(origData, crypted) 	origData = PKCS5UnPadding(origData) 	return origData }
 
 
  | 
 
2.3 PKCS5Padding
1 2 3 4 5 6
   |  func PKCS5Padding(ciphertext []byte, blockSize int) []byte { 	padding := blockSize - len(ciphertext)%blockSize 	padtext := bytes.Repeat([]byte{byte(padding)}, padding) 	return append(ciphertext, padtext...) }
 
  | 
 
2.4 PKCS5UnPadding
1 2 3 4 5 6 7 8
   |  func PKCS5UnPadding(origData []byte) []byte { 	length := len(origData) 	 	unpadding := int(origData[length-1]) 	return origData[:(length - unpadding)] }
 
 
  | 
 
2.5 ECB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
   | package ecb
  import "crypto/cipher"
  type ecb struct { 	b         cipher.Block 	blockSize int }
  func newECB(b cipher.Block) *ecb { 	return &ecb{ 		b:         b, 		blockSize: b.BlockSize(), 	} }
  type ecbEncrypter ecb
 
 
  func NewECBEncrypter(b cipher.Block) cipher.BlockMode { 	return (*ecbEncrypter)(newECB(b)) } func (x *ecbEncrypter) BlockSize() int { return x.blockSize } func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { 	if len(src)%x.blockSize != 0 { 		panic("crypto/cipher: input not full blocks") 	} 	if len(dst) < len(src) { 		panic("crypto/cipher: output smaller than input") 	} 	for len(src) > 0 { 		x.b.Encrypt(dst, src[:x.blockSize]) 		src = src[x.blockSize:] 		dst = dst[x.blockSize:] 	} }
  type ecbDecrypter ecb
 
 
  func NewECBDecrypter(b cipher.Block) cipher.BlockMode { 	return (*ecbDecrypter)(newECB(b)) } func (x *ecbDecrypter) BlockSize() int { return x.blockSize } func (x *ecbDecrypter) CryptBlocks(dst, src []byte) { 	if len(src)%x.blockSize != 0 { 		panic("crypto/cipher: input not full blocks") 	} 	if len(dst) < len(src) { 		panic("crypto/cipher: output smaller than input") 	} 	for len(src) > 0 { 		x.b.Decrypt(dst, src[:x.blockSize]) 		src = src[x.blockSize:] 		dst = dst[x.blockSize:] 	} }
   | 
 
参考资料
 golang AES/ECB/PKCS5 加密解密 url-safe-base64
aes加密解密,含 128、192、256位,cbc、cfb、ecb、ofb、pcbc模式
感谢网络上的大神!