美文网首页
Java(Android)、Golang、Node.js三种语言

Java(Android)、Golang、Node.js三种语言

作者: 路过麦田 | 来源:发表于2017-12-29 15:09 被阅读573次

    java(Android)版的AES加密
    public String encryptWithAES(String key, String message) {
        try {
            // Use md5 value as the real key
            byte[] b = key.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] keyData = md.digest(b);
    
            SecretKeySpec skey = new SecretKeySpec(keyData), "AES");
            // Create an 8-byte initialization vector
            byte[] iv = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
                    0x0e, 0x0f };
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
            
            Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            // CBC requires an initialization vector
            ecipher.init(Cipher.ENCRYPT_MODE, skey, paramSpec);
    
            byte[] plaintext = message.getBytes();
            byte[] result = ecipher.doFinal(plaintext, 0, plaintext.length);
            
            return Base64.encodeToString(result, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public String decryptWithAES(String key, String message) {
        try {
            // Use md5 value as the real key
            byte[] b = key.getBytes();
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] keyData = md.digest(b);
    
            SecretKeySpec skey = new SecretKeySpec(keyData), "AES");
            // Create an 8-byte initialization vector
            byte[] iv = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
                    0x0e, 0x0f };
            AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
            
            Cipher dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            // CBC requires an initialization vector
            dcipher.init(Cipher.DECRYPT_MODE, skey, paramSpec);
    
            byte[] messageData = Base64.decode(message, Base64.DEFAULT);
            byte[] result = dcipher.doFinal(messageData, 0, messageData.length);
            
            return new String(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    Node.js版AES加密
    
    let iv = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
        0x0e, 0x0f];
    
    function encrypt_with_aes(key, message) {
        let md5 = crypto.createHash('md5').update(key).digest('hex');
        const cipher = crypto.createCipheriv(
            'aes-128-cbc',
            new Buffer(md5, 'hex'),
            new Buffer(iv)
        );
        // cipher.setAutoPadding(true);
        var encrypted = cipher.update(message, 'utf8', 'base64');
        encrypted += cipher.final('base64');
        console.log('encode message: ' + encrypted);
        return encrypted;
    }
    
    function decrypt_with_aes(key, message) {
        let md5 = crypto.createHash('md5').update(key).digest('hex');
        const decipher = crypto.createDecipheriv(
            'aes-128-cbc',
            new Buffer(md5, 'hex'),
            new Buffer(iv)
        );
        var decrypted = decipher.update(message, 'base64', 'utf8');
        decrypted += decipher.final('utf8');
        console.log('decode message: ' + decrypted);
        return decrypted;
    }
    
    Golang版AES加密
    func EncryptWithAES(key, message string) string {
    
        hash := md5.New()
        hash.Write([]byte(key))
        keyData := hash.Sum(nil)
    
        block, err := aes.NewCipher(keyData)
        if err != nil {
            panic(err)
        }
    
        iv := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
    
        enc := cipher.NewCBCEncrypter(block, iv)
        content := PKCS5Padding([]byte(message), block.BlockSize())
        crypted := make([]byte, len(content))
        enc.CryptBlocks(crypted, content)
        return base64.StdEncoding.EncodeToString(crypted)
    }
    
    func DecryptWithAES(key, message string) string {
    
        hash := md5.New()
        hash.Write([]byte(key))
        keyData := hash.Sum(nil)
    
        block, err := aes.NewCipher(keyData)
        if err != nil {
            panic(err)
        }
    
        iv := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
        
        messageData, _ := base64.StdEncoding.DecodeString(message)
        dec := cipher.NewCBCDecrypter(block, iv)
        decrypted := make([]byte, len(messageData))
        dec.CryptBlocks(decrypted, messageData)
        return string(PKCS5Unpadding(decrypted))
    }
    
    func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
        padding := blockSize - len(ciphertext)%blockSize
        padtext := bytes.Repeat([]byte{byte(padding)}, padding)
        return append(ciphertext, padtext...)
    }
    
    func PKCS5Unpadding(encrypt []byte) []byte {
        padding := encrypt[len(encrypt)-1]
        return encrypt[:len(encrypt)-int(padding)]
    }
    

    Java版本和Node.js版本好久以前就已经在用了,所以相互之间加解密肯定没问题,但是这两天在弄的这个Golang版本的死活就是不通,还以为是Padding的时候算法不一样,后来几乎把网络上的Padding算法全部查遍了,都是一样的,也就是说Padding肯定是不会错的,最后一点点的排查才发现原来是key弄错了,加密时key的长度没有限制,但是AES128加密时key需要16位,所以这里就直接取key的MD5值,但是这个过程一不留心就出问题了。

    MD5算法是这样的

    func Md5(buf []byte) string {
        hash := md5.New()
        hash.Write(buf)
        return fmt.Sprintf("%x", hash.Sum(nil))
    }
    

    在key生成MD5后直接输出了hex后的字符串,然后对这个字符串直接转[]byte

    keyData := []byte(MD5([]byte(key)))
    

    这样就导致了key出错,搞了一下午才查出问题所在,看来以后敲代码还是得细心才行。

    相关文章

      网友评论

          本文标题:Java(Android)、Golang、Node.js三种语言

          本文链接:https://www.haomeiwen.com/subject/yovigxtx.html