我正在研究密钥协商协议。在一个点上卡住了,我想加密和发送消息从服务器和接收和解密在客户端。以下是服务器的代码片段。
”
// Generate an initialization vector (IV) for CBC mode
const EVP_CIPHER* cipher = EVP_aes_256_cbc(); // Use the desired cipher algorithm
EVP_CIPHER_CTX* ctx_encrypt = EVP_CIPHER_CTX_new();
const unsigned char* plaintext = sessionKey;
size_t plaintext_len = sessionKeyLen;
const int MAX_TEXT_LENGTH = 256;
unsigned char iv[EVP_MAX_IV_LENGTH];
// Initialize the encryption/decryption context
if (EVP_CipherInit_ex(ctx_encrypt, cipher, NULL, NULL, NULL, 1) != 1) {
fprintf(stderr, "Error initializing the cipher context\n");
EVP_CIPHER_CTX_free(ctx_encrypt);
return;
}
// Set the session key
if (EVP_CIPHER_CTX_set_key_length(ctx_encrypt, skeylen) != 1) {
fprintf(stderr, "Error setting the key length\n");
EVP_CIPHER_CTX_free(ctx_encrypt);
return;
}
if (EVP_CipherInit_ex(ctx_encrypt, NULL, NULL, skey, NULL, -1) != 1) {
fprintf(stderr, "Error setting the session key\n");
EVP_CIPHER_CTX_free(ctx_encrypt);
return;
}
if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) != 1) {
fprintf(stderr, "Error generating IV\n");
exit(1);
}
// Set the IV for the encryption operation
if (EVP_EncryptInit_ex(ctx_encrypt, EVP_aes_256_cbc(), NULL, skey, iv) != 1) {
fprintf(stderr, "Error setting encryption IV\n");
exit(1);
}
// Encrypt the plaintext (session key)
unsigned char ciphertext[MAX_TEXT_LENGTH + EVP_MAX_BLOCK_LENGTH];
int ciphertext_len;
if (EVP_EncryptUpdate(ctx_encrypt, ciphertext, &ciphertext_len, plaintext, plaintext_len) != 1) {
fprintf(stderr, "Error encrypting data\n");
exit(1);
}
// Finalize the encryption
int final_len;
if (EVP_EncryptFinal_ex(ctx_encrypt, ciphertext + ciphertext_len, &final_len) != 1) {
fprintf(stderr, "Error finalizing encryption\n");
exit(1);
}
ciphertext_len += final_len;
const size_t ivLength = EVP_CIPHER_iv_length(EVP_aes_256_cbc()); // Get the length of the IV
const size_t concatenatedMessageLength = ivLength + ciphertext_len;
unsigned char concatenatedMessage[concatenatedMessageLength];
memcpy(concatenatedMessage, iv, ivLength);
memcpy(concatenatedMessage + ivLength, ciphertext, ciphertext_len);
printf("Concatenated Message 1:\n");
for (size_t i = 0; i < concatenatedMessageLength; i++) {
printf("%02x", concatenatedMessage[i]);
}
printf("\n");
EVP_CIPHER_CTX_free(ctx_encrypt);
// Preparing for Bob's share
// Generate an initialization vector (IV) for CBC mode
plaintext = (const unsigned char*)"Verification Message SessionKey";
plaintext_len = strlen((const char*)plaintext);
EVP_CIPHER_CTX* ctx_encrypt2 = EVP_CIPHER_CTX_new();
// Initialize the encryption/decryption context
if (EVP_CipherInit_ex(ctx_encrypt2, cipher, NULL, NULL, NULL, 1) != 1) {
fprintf(stderr, "Error initializing the cipher context\n");
EVP_CIPHER_CTX_free(ctx_encrypt2);
return;
}
// Set the session key
if (EVP_CIPHER_CTX_set_key_length(ctx_encrypt2, sessionKeyLen) != 1) {
fprintf(stderr, "Error setting the key length\n");
EVP_CIPHER_CTX_free(ctx_encrypt2);
return;
}
if (EVP_CipherInit_ex(ctx_encrypt2, NULL, NULL, sessionKey, NULL, -1) != 1) {
fprintf(stderr, "Error setting the session key\n");
EVP_CIPHER_CTX_free(ctx_encrypt2);
return;
}
if (RAND_bytes(iv, EVP_MAX_IV_LENGTH) != 1) {
fprintf(stderr, "Error generating IV\n");
exit(1);
}
// Set the IV for the encryption operation
if (EVP_EncryptInit_ex(ctx_encrypt2, EVP_aes_256_cbc(), NULL, sessionKey, iv) != 1) {
fprintf(stderr, "Error setting encryption IV\n");
exit(1);
}
// Encrypt the plaintext (Bob's share)
if (EVP_EncryptUpdate(ctx_encrypt2, ciphertext, &ciphertext_len, plaintext, plaintext_len) != 1) {
fprintf(stderr, "Error encrypting data\n");
exit(1);
}
// Finalize the encryption
if (EVP_EncryptFinal_ex(ctx_encrypt2, ciphertext + ciphertext_len, &final_len) != 1) {
fprintf(stderr, "Error finalizing encryption\n");
exit(1);
}
ciphertext_len += final_len;
const size_t concatenatedMessageLength2 = ivLength + ciphertext_len;
unsigned char concatenatedMessage2[concatenatedMessageLength2];
memcpy(concatenatedMessage2, iv, ivLength);
memcpy(concatenatedMessage2 + ivLength, ciphertext, ciphertext_len);
printf("Concatenated Message 2:\n");
for (size_t i = 0; i < concatenatedMessageLength2; i++) {
printf("%02x", concatenatedMessage2[i]);
}
printf("\n");
EVP_CIPHER_CTX_free(ctx_encrypt2);
// Sending Server Share and Verification Message
if (concatenatedMessageLength > 0) {
send(client_sock_Bob, concatenatedMessage, concatenatedMessageLength, 0);
// Send the encrypted hash to the server
usleep(100);
if (concatenatedMessageLength2 > 0) {
send(client_sock_Bob, concatenatedMessage2, concatenatedMessageLength2, 0);
} else {
printf("Server Verification message is Null: %s\n");
}
} else {
printf("Session key is Null : %s\n");
}`
在此代码中,要加密的第一条消息是一个sessionkey,由密钥'skey'(一个数组)加密。下一条消息由会话密钥加密。在客户端,客户端只有skey(一个数组),它将首先解密并获得会话密钥,然后使用该会话密钥解密下一条消息。下面是代码
`const EVP_CIPHER* cipher = EVP_aes_256_cbc(); // Use the desired cipher algorithm
EVP_CIPHER_CTX* ctx_decrypt = EVP_CIPHER_CTX_new();
char decryptedText1[1024] = {0};
char decryptedText2[1024] = {0};
int decryptedText1_len = 0;
int decryptedText2_len = 0;
memset(decryptedText1, 0, sizeof(decryptedText1));
// Initialize the encryption/decryption context
if (EVP_CipherInit_ex(ctx_decrypt, cipher, NULL, NULL, NULL, 1) != 1) {
fprintf(stderr, "Error initializing the cipher context\n");
EVP_CIPHER_CTX_free(ctx_decrypt);
return;
}
// Set the session key
if (EVP_CIPHER_CTX_set_key_length(ctx_decrypt, skeylen) != 1) {
fprintf(stderr, "Error setting the key length\n");
EVP_CIPHER_CTX_free(ctx_decrypt);
return;
}
if (EVP_CipherInit_ex(ctx_decrypt, NULL, NULL, skey, NULL, -1) != 1) {
fprintf(stderr, "Error setting the session key\n");
EVP_CIPHER_CTX_free(ctx_decrypt);
return;
}
// Extract the IV from the concatenated message 2
memcpy(iv, concatenatedMessage2, EVP_MAX_IV_LENGTH);
// Set the IV for the decryption operation
if (EVP_DecryptInit_ex(ctx_decrypt, EVP_aes_256_cbc(), NULL, skey, iv) != 1) {
fprintf(stderr, "Error setting decryption IV\n");
exit(1);
}
// Decrypt the ciphertext
if (EVP_DecryptUpdate(ctx_decrypt, decryptedText1, &decryptedText1_len, concatenatedMessage2 + EVP_MAX_IV_LENGTH, concatenatedMessageLength2 - EVP_MAX_IV_LENGTH) != 1) {
fprintf(stderr, "Error decrypting data\n");
exit(1);
}
// Finalize the decryption
int final_len;
if (EVP_DecryptFinal_ex(ctx_decrypt, decryptedText1 + decryptedText1_len, &final_len) != 1) {
fprintf(stderr, "Error finalizing decryption\n");
exit(1);
}
decryptedText1_len += final_len;
// Print the decrypted plaintext
printf("Decrypted Text: %.*s\n", decryptedText1_len, decryptedText1);
EVP_CIPHER_CTX_free(ctx_decrypt);
EVP_CIPHER_CTX* ctx_decrypt2 = EVP_CIPHER_CTX_new();
// Initialize the encryption/decryption context
if (EVP_CipherInit_ex(ctx_decrypt2, cipher, NULL, NULL, NULL, 1) != 1) {
fprintf(stderr, "Error initializing the cipher context\n");
EVP_CIPHER_CTX_free(ctx_decrypt2);
return;
}
// Set the session key
if (EVP_CIPHER_CTX_set_key_length(ctx_decrypt2, decryptedText1_len) != 1) {
fprintf(stderr, "Error setting the key length\n");
EVP_CIPHER_CTX_free(ctx_decrypt2);
return;
}
if (EVP_CipherInit_ex(ctx_decrypt2, NULL, NULL, decryptedText1, NULL, -1) != 1) {
fprintf(stderr, "Error setting the session key\n");
EVP_CIPHER_CTX_free(ctx_decrypt2);
return;
}
// Extract the IV from the concatenated message 1
memcpy(iv, concatenatedMessage1, EVP_MAX_IV_LENGTH);
// Set the IV for the decryption operation
if (EVP_DecryptInit_ex(ctx_decrypt2, EVP_aes_256_cbc(), NULL, decryptedText1, iv) != 1) {
fprintf(stderr, "Error setting decryption IV\n");
exit(1);
}
// Decrypt the ciphertext
if (EVP_DecryptUpdate(ctx_decrypt2, decryptedText2, &decryptedText2_len, concatenatedMessage1 + EVP_MAX_IV_LENGTH, concatenatedMessageLength1 - EVP_MAX_IV_LENGTH) != 1) {
fprintf(stderr, "Error decrypting data\n");
exit(1);
}
// Finalize the decryption
if (EVP_DecryptFinal_ex(ctx_decrypt2, decryptedText2 + decryptedText2_len, &final_len) != 1) {
fprintf(stderr, "Error finalizing decryption\n");
exit(1);
}
decryptedText2_len += final_len;
// Print the decrypted plaintext
printf("Decrypted Text: %.*s\n", decryptedText2_len, decryptedText2);
我面临的问题是在解密。它在解密第一消息时卡住,给出“错误解密数据”作为输出。我已经在两端验证了skey和iv。我会很感激你的帮助
2条答案
按热度按时间2nbm6dog1#
正如评论所指出的,你有:
当它应该是:
例如,您使用concatenatedMessage2 iv来解密concatenatedMessage1,使用concatenatedMessage1 iv来解密concatenatedMessage2。
sdnqo3pr2#
我做了一些调试,得到了这个错误。concatenatedmessagelength1在另一个函数中被更新时,它正在向您发送。(虽然是全球性的)。然而,现在我被卡在下一个错误
if (EVP_DecryptFinal_ex(ctx_decrypt, decryptedText1 + decryptedText1_len, &final_len) != 1) { fprintf(stderr, "Error finalizing decryption\n"); exit(1); }
在调试时,我发现decryptedText1_len是32,这是正确的(我们的会话密钥是32字节),但是,在检查变量decryptedText1时,它有48个字节。