So, we have an existing application that stores the version,iv,secret in a database, base64 encoded, encrypted with a symmetric cipher as we need the plaintext in a challenge response. Decryption in Python is done like so
version, b64_iv, b64_ciphertext = bstring.split(b',')
iv = base64.b64decode(b64_iv)
ciphertext = base64.b64decode(b64_ciphertext)
decryptor = AES.new(self.key, self.mode, IV=iv)
bytestring = decryptor.decrypt(ciphertext)
If I do this directly with openssl in C/C++ it is like so
EVP_DecryptInit_ex(ctx, EVP_aes_128_cfb8(), NULL, key, iv);
unsigned char *plaintext_p = (unsigned char *)plaintext;
for (int i = 0; i < input_size; i++) {
if (!EVP_DecryptUpdate(ctx, plaintext_p, &outlen, &ciphertext[i], 1)) {
merrorf("decrypt_aes: EVP_DecryptUpdate returned an error");
free(plaintext);
return NULL;
}
plaintext_p += outlen;
}
if (!EVP_DecryptFinal(ctx, plaintext_p, &outlen)) {
merrorf("decrypt_aes: EVP_DecryptFinal returned an error");
free(plaintext);
return NULL;
}
plaintext_p += outlen;
*plaintext_p = '\0';
EVP_CIPHER_CTX_free(ctx);
return (unsigned char *)plaintext;
Now, in Go, I don't see a way to specify the cipher to EVP_aes_128_cfb8. I know that since I'm using a 16-character key, 128-bit will be used, but I'm not certain of the rest, and the passwords are not decrypting properly.
package main
import (
"crypto/sha1"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"net/url"
"os"
"strings"
"fmt"
)
func main() {
key := "bigsecretdon'ttellanyone"
sha_key := sha1.Sum([]byte(key))
key_slice := sha_key[:16]
encpass := "e0,cxMarJhf8bGHe+Vko1uxdw==,9InGiLOqWB/OZsLGBqW4tlk="
// Split the input
pieces := strings.Split(encpass, ",")
if (len(pieces) != 3) {
panic("Invalid password string")
}
iv, err := base64.StdEncoding.DecodeString(pieces[1])
if err != nil {
panic(err)
}
password, err := base64.StdEncoding.DecodeString(pieces[2])
if err != nil {
panic(err)
}
// The 16-bit key slice ensures 128-bit
block, err := aes.NewCipher(key_slice)
if err != nil {
panic(err)
}
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(password, password)
fmt.Printf("%s\n", password)
}
The plaintext password is not correct so I am clearly doing something wrong, but I find the documentation unhelpful and I'm not sure what to do here.
Help appreciated.