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

clawhub · · 2474 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

重要:

在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模式

感谢网络上的大神!


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:clawhub

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

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2474 次点击  
加入收藏 微博
1 回复  |  直到 2020-06-28 13:43:06
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传