Перейти эквивалентный OpenSSL EVP симметричный EVP_aes_256_cbc

Я пишу скрипт Go, который расшифровывает некоторые устаревшие данные, зашифрованные с помощью EVP_aes_256_cbc и открытый ключ RSA.

В Си это будет что-то вроде:

key_size = EVP_OpenInit(&ctx, EVP_aes_256_cbc(), evp_key, eklen, iv, pkey);
//...
EVP_OpenUpdate(&ctx, destination, &len_out, buffer_in, buffer_size)
//...
EVP_OpenFinal(&ctx, destination+len_out, &len_out);

у меня есть evp_key а также iv эквиваленты байтового массива в Go, но я должен признаться, что EVP работает в OpenSSL, ускользает от меня (я достаточно компетентен в C, но я не могу понять процесс, с помощью которого происходит расшифровка, глядя на OpenSSL источник.)

В Go я могу получить это далеко:

pKey := //rsa.PrivateKey
eklen := 32
evpKey := "// hidden 32 byte array"
iv := "// hidden 16 byte array"

c, err := aes.NewCipher(iv)
cbc := cipher.NewCBCDecrypter(c, iv)

И вот тут я заблудился. у меня есть evpKey и pKey, но я не уверен, как расшифровать данные отсюда. OpenSSL использует RSA_decrypt_old или что-то подобное, но я не могу отследить, что это на самом деле означает.

Есть ли эквивалент Go или мне нужно выбить слишком дорого cgo упаковывать и закатывать рукава?

Обновление (разрешение):

Для тех, кто хочет повторить поведение EVP в Go или просто интересуется, как именно работает EVP, ниже приводится разбивка. Если вы знаете, что C (или Java или любая другая реализация OpenSSL) шифрует что-то вроде:

// pseudo-code: don't copypasta and expect amazing
EVP_PKEY_assign_RSA(pkey, public_key);
EVP_CIPHER_CTX_init(&ctx);
EVP_SealInit(&ctx, EVP_aes_256_cbc(), &evp_key, &evp_key_len, iv, &pkey, 1);
EVP_SealUpdate(&ctx, buffer_out, &encrypt_len, (unsigned char*)buffer_in, len);
EVP_SealFinal(&ctx, buffer_out+encrypt_len, &encrypt_len);

"Печать" фактически просто шифрует ключ с помощью открытого ключа RSA.

В Go расшифровать что-то подобное:

evpKeyBytes := "// the rsa.PublicKey encoded evpKey"
evpKey, err := rsa.DecryptPKCS1v15(rand.Reader, PrivateKeyRSA, evpKeyBytes)
c, err := aes.NewCipher(evpKey)
cbc := cipher.NewCBCDecrypter(c, iv)
decryptedDataBytes := make([]bytes, 2048) // some message size
cbc.CryptBlocks(decryptedDataBytes, encryptedDataBytes)
data = string(decryptedDataBytes)
// data should have the expected decrypted result.

1 ответ

Решение

NewCipher ожидает, что ключ не iv, и, поскольку вы передаете ему 128-битный iv, он работает как aes128cbc.

Другие вопросы по тегам