0

This is a 4 year old nodejs project I took over, and I was asked to refactor it using golang, but in the refactoring I found that the nodejs encryption was deprecated. And, I don't know which mode of AES is used to encrypt this code

Can any expert help me to see how to decrypt this nodejs encryption with golang? Thank you very much!

Encryption code for nodejs :

exports.createToken = function (src: string, timestamp: string, key: any) {
    var msg = src + '|' + timestamp;
    var cipher: any = CryptoJS.createCipher('aes256', key);
    var enc: any = cipher.update(msg, 'utf8', 'hex');
    enc += cipher.final('hex');
    return enc;
};

Decryption code for nodejs :

exports.parseToken = function (token: string, key: string): any {
    let decipher = CryptoJS.createDecipher('aes256', key);
    let dec: string;
    try {
        dec = decipher.update(token, 'hex', 'utf8');
        dec += decipher.final('utf8');
    } catch (err) {
        console.error('[token] fail to decrypt token. %j', token);
        return null;
    }
    var ts = dec.split('|');
    if (ts.length !== 2) {
        // illegal token
        return null;
    }
    return { src: ts[0], timestamp: Number(ts[1]) };
};
Topaco
  • 40,594
  • 4
  • 35
  • 62

1 Answers1

2

The deprecated methods crypto.createCipher() and crypto.createDecipher() apply the proprietary OpenSSL function EVP_BytesToKey() to derive a 32 bytes key and a 16 bytes IV from a password. No salt is used, the digest MD5 and an iteration count of 1. This algorithm is very insecure, which is why both methods are deprecated.

The posted code applies aes-256-cbc (i.e. AES-256 in CBC mode) and just this key derivation to derive a key/IV pair. Since the key derivation does not use a salt, always the same ciphertext results for the same plaintext and password. E.g. for:

var src = 'The quick brown fox jumps over the lazy dog';
var timestamp = '1616409134831';
var passphrase = 'my secret passphrase';

the ciphertext is:

60673700fb64da36b65829ee3c578d1ec675638a95c8dee4e7c026ee72a837c2170c13b7b24125c02871663a64fd646dd9994793943eeb70b3e959cbc4cd423a

So for decryption in Go you need an implementation of EVP_BytesToKey(), e.g. here:

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "fmt"
    "github.com/walkert/go-evp"
    "encoding/hex"  
)
func main() {

    key, iv := evp.BytesToKeyAES256CBCMD5([]byte(""), []byte("my secret passphrase")) // MD5, no salt, passprase: my secret passphrase  
    ciphertext, _ := hex.DecodeString("60673700fb64da36b65829ee3c578d1ec675638a95c8dee4e7c026ee72a837c2170c13b7b24125c02871663a64fd646dd9994793943eeb70b3e959cbc4cd423a")
    
    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err)
    }
    cbc := cipher.NewCBCDecrypter(block, iv)
    
    plaintextPadded := make([]byte, len(ciphertext))                    
    cbc.CryptBlocks(plaintextPadded , ciphertext)
    
    plaintext := string(PKCS7Unpad(plaintextPadded )) 
    fmt.Println("Decrypted data: ", string(plaintext))
}

func PKCS7Unpad(src []byte) []byte { // PKCS7 unpadding from https://stackoverflow.com/a/41595640/9014097
        length := len(src)
        unpadding := int(src[length-1])
        return src[:(length - unpadding)]
}

Running this code results in the above plaintext.

Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Thank you so much for your reply, your code was very helpful and solved my current anxiety. It has taught me more than I ever knew. Again, my thanks and have a great life! – user15287616 Mar 22 '21 at 12:01
  • I am very sorry to disturb you again,Your last answer was very helpful, but could you please tell me again how to implement the above Nodejs encryption logic using Golang?Ik heb geprobeerd om de code te back-propageren zoals je het in Golang hebt gedecodeerd, maar ik weet niet wat het probleem is dat me verhindert om hetzelfde coderingsresultaat te krijgen als in Nodejs hierboven @user15287616 – user15287616 Aug 23 '21 at 12:34
  • @user15287616 - This can't be answered in the context of a comment. You should post a new question on SO with all the information needed to answer it (check first if there is already a post that answers your question). If necessary, you can reference this post. – Topaco Aug 23 '21 at 12:42
  • Thank you for your reply and advice and I have resubmitted a new question, if you have time, you can help me by following the link to the new question https://stackoverflow.com/questions/68893268/how-can-i-use-goalng-to-implement-a-deprecated-encryption-method-from-nodejs @user15287616 – user15287616 Aug 23 '21 at 13:09