Reputation: 95
Code in Vuejs -
var message = "Hello World"
var keyBytes = aesjs.utils.utf8.toBytes("akey123")
var iv = CryptoJS.lib.WordArray.random(8).toString()
var ivBytes = aesjs.utils.utf8.toBytes(iv)
var messageBytes = aesjs.utils.utf8.toBytes(message);
var aesCfb = new aesjs.ModeOfOperation.cfb(keyBytes, ivBytes);
var encryptedBytes = aesCfb.encrypt(messageBytes);
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
Data that I send to GO - {"iv": iv, "cipher": encryptedHex}
Code in GO
func DecryptCipher(iv, cipher string) {
key := []byte("akey123")
iv := []byte(iv)
cipherText, _ := hex.DecodeString(cipher)
block, err := aes.NewCipher(key)
if err != nil {
log.Println(err)
}
cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(cipherText, cipherText)
fmt.Println("data", string(cipherText))
}
Expected Output: "Hello World" Actual Output: @�Sa 1���Ig{�
Can someone please help me and tell me what is it that I am missing in the code above. Thank you in advance!
Upvotes: 2
Views: 1407
Reputation: 49121
There are several flaws in both codes that prevent the execution. However, since both are running on your system, these seem to be copy/paste errors:
iv
and cipher
.After these fixes, the programs are executed, but the decryption fails. The problem is caused by different CFB variants: In the aes-js-code, CFB8 is used and in the Go-code, CFB128. Here the digits denote the number of bits that are shifted in the shift register [1].
Go only supports CFB128, at least without deeper modifications [2][3].
aes-js uses CFB8 by default. However, the CFB variant can also be defined explicitly with the third parameter of the cfb constructor. A change to CFB128 is possible with [4]:
var segmentSize = 16;
var aesCfb = new aesjs.ModeOfOperation.cfb(keyBytes, ivBytes, segmentSize);
Note that the value must be specified in bytes, i.e. 1 corresponds to CFB8 and 16 to CFB128.
CFB is a stream cipher, so that a plaintext of arbitrary length can be encrypted without padding and the length of the ciphertext equals that of the plaintext [5]. Unfortunately there seems to be a bug in aes-js [6] which requires that the length of the plaintext is an integer multiple of the segment size, i.e. 16 bytes in the case of CFB128. Otherwise, the following error message is displayed:
invalid plaintext size (must be segmentSize bytes)
I.e., if the plaintexts used don't already have this length, the bug requires explicit padding, although a stream cipher wouldn't actually require padding.
Against the background of these problems, you may want to use either a different mode or different libraries.
Besides:
CryptoJS.lib.WordArray.random(8)
a WordArray
with random 8 bytes is created and encoded as a hexadecimal string with a length of 16 bytes using toString()
. This hexadecimal string is Utf8-encoded and is therefore identical in both codes. Nevertheless, the remarks on the IV in the comment are of course correct. Upvotes: 1