OpenSSL EVP_DecryptFinal_ex解密失败问题求助
AES-ECB解密时EVP_DecryptFinal_ex调用失败问题
我尝试用OpenSSL实现AES-ECB模式的加解密,所有初始化步骤都返回成功,但最终调用EVP_DecryptFinal_ex时解密失败。已确认输入和密钥长度均能被16整除,参考过相关Stack Overflow线程及OpenSSL官方手册,试过同类问题的解决方案仍未解决,该函数返回0表示解密失败,无法定位具体原因。
代码实现
#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> #include <openssl/conf.h> #include <openssl/evp.h> #include <openssl/err.h> const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int b64invs[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; int b64_decode(const char *bytes, unsigned char *out, size_t *outlen) { size_t len; size_t i; size_t j; int v; if (bytes == NULL) return 1; len = strlen(bytes); size_t b64_decoded_size = 9; b64_decoded_size = len / 4 * 3; for (i=len; i-->0; ) { if (bytes[i] == '=') { b64_decoded_size--; } else { break; } } if (*outlen < b64_decoded_size || len % 4 != 0 || out == NULL) { *outlen = b64_decoded_size; return 2; } else { *outlen = b64_decoded_size; } for (i=0; i<len; i++) { bool invalid_char = true; if (bytes[i] >= '0' && bytes[i] <= '9') invalid_char = false; else if (bytes[i] >= 'A' && bytes[i] <= 'Z') invalid_char = false; else if (bytes[i] >= 'a' && bytes[i] <= 'z') invalid_char = false; else if (bytes[i] == '+' || bytes[i] == '/' || bytes[i] == '=') invalid_char = false; if (invalid_char == true) return 3; } for (i=0, j=0; i<len; i+=4, j+=3) { v = b64invs[bytes[i]-43]; v = (v << 6) | b64invs[bytes[i+1]-43]; v = bytes[i+2]=='=' ? v << 6 : (v << 6) | b64invs[bytes[i+2]-43]; v = bytes[i+3]=='=' ? v << 6 : (v << 6) | b64invs[bytes[i+3]-43]; out[j] = (v >> 16) & 0xFF; if (bytes[i+2] != '=') out[j+1] = (v >> 8) & 0xFF; if (bytes[i+3] != '=') out[j+2] = v & 0xFF; } return 0; } int main () { //Lyrics to yellow submarine, padded with spaces to make length 1200. unsigned char cipher_text[] = "kG/VjeOGoBnNfTnWm2zRI/Tr6bmqtbN7bOpbcL4ZIUegmblOVZECN9U6Na13W/2r0IPsgIgkhbhJTHVh39O9iS8BE8maJVxXko6h6QOWjHXE5o+EcWxbwdpA0usHv8RR+RZzAaNEpFmWWUoVr6egmdnAyWV1gd0VLiRZhB1/swfU5gpwQ0PzcUXcnkbJB0sXvfDAVt9WPvvRA6L2+r22NdHnZztHfwe/cIvhJqMHhK2LAUQnV4y1lmT0xhUbybtcQng5uVXFf1oHrDk/Wa+eMqGh+S9byjDa5X815wj0nI01rd5xjJZK+5Cybm9YrUG6mO5Oh/e0b+hJrBOcSbsm+lRuPI6JfyBaXvw2O/HedLyr7iGg1TM2NCF3eb5iYDCDXK+avahsn71WOQC7Vaxt/XY2+sjI3fMndNkFSj+0ruKm69aeTnNJAEsNiIM1+xWlZOhKg52wIhL3n6DpdIfSAsjfNY/ijK+uszvRUZzMBqFwR9mIUyKM0m9UJryjKIz1St1KbiILeMZjb0neW32N9LiUxOKkp2OhQ8vm4BZiUFPQYeWn1JYqjCxRVwQw8jqqsO0/J+4GPGCXV8YWgFlyZCT/eNQh3M4wy3oMXQcamxEnK1YfbTpfxWaaMM8vQzjwb3caeyJtE3xX4iy80Ln1hNHxOeUXI6W0UfJZTzzbM7HJacaeTi4xFPOdEqy8BQpfojfZ+JD8Na6k1yaeb4mJRZOpRrSsWpA24rK5a2m4FCX/f4aA1T+5zejHBqfUnIWopibiWLS+irtXOfzJewhKVFpzi8Xkm1DNxQmXsfu93Cplt2YPlKuU+wzuCBguESgWFohVZIiW8gjBqba4MNcsaNEhwSlQmEhbMwN+VKpbf/5D1bhccyxgw35TwLA6AZrMTrZweY+lnXf81zSeWcRn2hQQbm/lbkrJ+YUgV2o3ewer1n2vrv3xwjCxjHGnfVUj6k5lJXPuRsJX/ehf9MtEBb7P6seErlaOkHuaSrutaGcjBXVEie7kZItqGECox5Sh5ig47bkKO0xe181NAVJF2pJkKpV9g19EWqLINOMRGYIuCaG5dlIf5hbnTPNnOk23z7WBUs3QF/DpAIp6w3mS3AELAgXXAWgN8m3xXu6yV+Y14g7sMYjFdxcTbQbD4w8U04X3ip1EZwB77PRJtG4/ONknBCJ6lO3J7kd2YnM0aiAWeIYmDRK3R3r7mJy9z3Ex7efxiyDOwbXPSbcVtpfN76UVQBPkFgCQRHAgmfUpaxpjGK/YgDd3nGONZJiB38A+HpnqcRznTf4szPvgKNM9l4kK8Q3/XfMJXMeXY8qve0fEqvCvtMNFQ+GKFrWnjzbv038ycC6QZKLTae/x1k0NQvGPNqRF82NZvb+mc+cozY/mzeOqOnq+4Kp3qeQPO1C97Dnr89eRTo8UG4r7kdNGKaGh+S9byjDa5X815wj0nI2Yjq8gtmgtw6HQ/1nZBUKOtNT/utkpPaBz+UpZB3pMnqsicBV2iRXas2BpMrhtCHJGUEBVkKjE9X2sy6cqCV3C6YUL7nlJeXRpUEwaktT04wMDjDXsAG8m0SG2lJY3e2IJCxCAisCtDCsmagO0cfhV"; unsigned char key[] = "YELLOW SUBMARINE"; size_t cipher_bytes_len = 0; size_t cipher_text_len = strlen((const char *)cipher_text); b64_decode((const char *)cipher_text, NULL, &cipher_bytes_len); unsigned char cipher_bytes[cipher_bytes_len]; b64_decode((const char *)cipher_text, cipher_bytes, &cipher_bytes_len); printf("cipher_text_len = %ld\n", cipher_text_len); printf("cipher_bytes_len = %ld\n", cipher_bytes_len); EVP_CIPHER_CTX *ctx; int len; unsigned char plain[1584]; if(!(ctx = EVP_CIPHER_CTX_new())) return 4; if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL)) return 5; if(1 != EVP_DecryptUpdate(ctx, plain, &len, cipher_text, cipher_text_len)) return 6; int plain_len = len; printf("len = %d\n", len); printf("EVP_DecryptFinal_ex(ctx, plain + len, &len) = %d\n", EVP_DecryptFinal_ex(ctx, plain + plain_len, &len)); EVP_CIPHER_CTX_free(ctx); return 0; }
编译命令
gcc main.c -lcrypto
内容的提问来源于stack exchange,提问作者DavidT
相关产品推荐
相关产品推荐

