gpt4 book ai didi

Java和openssl C不同的AES CTR加密结果

转载 作者:行者123 更新时间:2023-11-30 16:57:18 24 4
gpt4 key购买 nike

我需要将应用程序从 Java 移植到 C++。我陷入了 AES CTR 128 的问题。在 Java 和 C 中它有不同的加密结果。所以我的 Java 代码。

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;


class HelloWorld {
public static void main(String[] args) {
try
{

byte[] keyBytes = Base64.getDecoder().decode("5gYDRl00XcjqlcC5okdBSfDx46HIGZBMAvMiibVYixc=");
byte[] ivBytes = Base64.getDecoder().decode("AAAAAAAAAAAAAAAAAAAAAA==");

SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec iv = new IvParameterSpec(ivBytes);

Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
String encrypted = Base64.getEncoder().encodeToString(cipher.doFinal("This is a plaintext message.".getBytes()));
System.out.println(encrypted); // print: sTBJYaaGNTxCErAXbP6eXnU59Yyn1UJAp7MGQw==

} catch (Exception e) {}
return;
}
}

我的 C 代码。我使用相同的算法、纯文本、 key 和 iv。但得到另一个密文结果。

#include <openssl/conf.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>

char *base64encode (const void *b64_encode_this, int encode_this_many_bytes)
{
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
BUF_MEM *mem_bio_mem_ptr; //Pointer to a "memory BIO" structure holding our base64 data.
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory sink BIO.
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-sink BIO chain.
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //No newlines every 64 characters or less.
BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data.
BIO_flush(b64_bio); //Flush data. Necessary for b64 encoding, because of pad characters.
BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr); //Store address of mem_bio's memory structure.
BIO_set_close(mem_bio, BIO_NOCLOSE); //Permit access to mem_ptr after BIOs are destroyed.
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1); //Makes space for end null.
(*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0'; //Adds null-terminator to tail.
return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct).
}

char *base64decode (const void *b64_decode_this, int decode_this_many_bytes)
{
BIO *b64_bio, *mem_bio; //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null.
b64_bio = BIO_new(BIO_f_base64()); //Initialize our base64 filter BIO.
mem_bio = BIO_new(BIO_s_mem()); //Initialize our memory source BIO.
BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source.
BIO_push(b64_bio, mem_bio); //Link the BIOs by creating a filter-source BIO chain.
BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines.
int decoded_byte_index = 0; //Index where the next base64_decoded byte should be written.
while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte.
decoded_byte_index++; //Increment the index until read of BIO decoded data is complete.
} //Once we're done reading decoded data, BIO_read returns -1 even though there's no error.
BIO_free_all(b64_bio); //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
return base64_decoded; //Returns base-64 decoded data with trailing null terminator.
}

int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;

int len;

int ciphertext_len;

/* Create and initialise the context */
ctx = EVP_CIPHER_CTX_new();

/* Initialise the encryption operation */
EVP_EncryptInit_ex(ctx, EVP_aes_128_ctr(), NULL, key, iv);

/* Provide the message to be encrypted, and obtain the encrypted output.
* EVP_EncryptUpdate can be called multiple times if necessary
*/
EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len);
ciphertext_len = len;

/* Finalise the encryption. Further ciphertext bytes may be written at
* this stage.
*/
EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
ciphertext_len += len;

/* Clean up */
EVP_CIPHER_CTX_free(ctx);

return ciphertext_len;
}

int main (void)
{
/* A 256 bit key */
char keyStr[] = "5gYDRl00XcjqlcC5okdBSfDx46HIGZBMAvMiibVYixc=";
unsigned char *key = (unsigned char *)base64decode(keyStr, strlen(keyStr));

/* A 128 bit IV */
char ivStr[] = "AAAAAAAAAAAAAAAAAAAAAA==";
unsigned char *iv = (unsigned char *)base64decode(ivStr, strlen(ivStr));

/* Message to be encrypted */
unsigned char *plaintext = (unsigned char *)"This is a plaintext message.";

/* Buffer for ciphertext */
unsigned char ciphertext[128];
int ciphertext_len;

/* Initialise the library */
OpenSSL_add_all_algorithms();
OPENSSL_config(NULL);

/* Encrypt the plaintext */
ciphertext_len = encrypt (plaintext, strlen ((char *)plaintext), key, iv,
ciphertext);

/* Encode with Base64 */
char *ciphertextBase64 = base64encode(ciphertext, strlen(ciphertext));
printf("Ciphertext is: %s\n", ciphertextBase64); /* print: UL4lvWZNtDVO64ywHVkFM/uBv+lpE3DhGZrRcw== */

/* Clean up */
EVP_cleanup();

return 0;
}

那么我如何才能在 C 中获得相同的结果 sTBJYaaGNTxCErAXbP6eXnU59Yyn1UJAp7MGQw==

最佳答案

这里 AES CTR 256 而不是 128。Java 没有显式定义它从 key 大小隐式获取的位。所以这里 key 大小为 32 字节 - 256 位。我错误地认为这里 AES CTR 128。

关于Java和openssl C不同的AES CTR加密结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39593800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com