OpenSSL RSA 加密的一个认知盲区

原本对 RSA 不同加密方式的区别和使用场景还是很清楚的。今天在实现一个 RSA 加密功能时,发现公钥加密结果每次都不一样,这个现象触发了我的盲区。查阅相关资料后,记录一下背后的原理。 问题现象 以下代码使用 OpenSSL 的 EVP API 进行 RSA 加密,没有显式传入随机值,但每次运行结果都不相同: 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 26 27 28 29 30 31 unsigned char *encode_by_rsa(const char *public_key, unsigned const char *input) { int key_len = (int) strlen(public_key); BIO *bio = BIO_new_mem_buf(public_key, key_len); EVP_PKEY *pKey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); BIO_free_all(bio); EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pKey, NULL); EVP_PKEY_encrypt_init(ctx); EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256()); EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256()); size_t rsa_len = (int) RSA_LENGTH; unsigned char *encrypted_data = malloc(rsa_len + 1); memset(encrypted_data, 0, rsa_len + 1); if (encrypted_data == NULL) { return NULL; } int input_len = (int) strlen((const char *) input); EVP_PKEY_encrypt(ctx, encrypted_data, &rsa_len, input, input_len); encrypted_data[rsa_len] = '\0'; EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pKey); return encrypted_data; } 原因:随机填充 不管是 RSA 私钥签名还是公钥加密,操作中都需要对待处理数据先进行填充,再对填充后的数据进行加密运算。 填充过程中引入了伪随机数,所以即使相同的输入和密钥,每次输出都不同。 ...

2022年8月8日 · 2 分钟 · haoxiqiang

HTTPS 相关记录

使用 HTTPS 建议先阅读 Android 官方 Training: Security with SSL。很多公司已经全站 HTTPS,但有些用法并不正确。这里简单记录一下自己遇到的问题。 ...

2016年1月20日 · 3 分钟 · haoxiqiang