转载

不带模式和填充来获取AES算法-JAVA与Golang的互通

重要:

在Java中不带模式和填充来获取AES算法的时候,其默认使用AES/ECB/PKCS5Padding!!!

1 Java的AES加解密

如果把Cipher.getInstance("AES");中的"AES"换成"AES/ECB/PKCS5Padding",效果是一样的。

1.1 加密操作

/**
     * Description: 加密操作 <br>
     *
     * @param data 待加密数据
     * @param key  密钥
     * @return 加解密后的信息
     * @throws Exception <br>
     */
    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 解密操作

/**
     * Description: 解密操作 <br>
     *
     * @param data 待解密数据
     * @param key  密钥
     * @return 解密后的信息
     * @throws Exception <br>
     */
    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 加密操作

//ECB PKCS5 加密
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 解密操作

//ECB PKCS5 解密
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

//PKCS5Padding
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

//PKCS5UnPadding
func PKCS5UnPadding(origData []byte) []byte {
    length := len(origData)
    // 去掉最后一个字节 unpadding 次
    unpadding := int(origData[length-1])
    return origData[:(length - unpadding)]
}

2.5 ECB

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

// NewECBEncrypter returns a BlockMode which encrypts in electronic code book
// mode, using the given Block.
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

// NewECBDecrypter returns a BlockMode which decrypts in electronic code book
// mode, using the given Block.
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模式

感谢网络上的大神!

原文  https://studygolang.com/articles/19223
正文到此结束
Loading...