将OpenSSL RSA加密代码迁移至GnuTLS遇格式问题求助
解决GnuTLS RSA加密匹配OpenSSL RSA_PKCS1_OAEP_PADDING的问题
你遇到的核心问题是:GnuTLS的gnutls_pubkey_encrypt_data默认使用PKCS#1 v1.5填充,而你需要的是和OpenSSLRSA_PKCS1_OAEP_PADDING对应的PKCS#1 OAEP填充模式。下面是具体的修改方案和解释:
问题根源
OpenSSL的RSA_public_encrypt使用RSA_PKCS1_OAEP_PADDING时,默认采用以下配置:
- 哈希算法:SHA-1
- MGF1掩码生成函数的哈希算法:与主哈希一致(SHA-1)
- 无附加编码数据(空label)
而GnuTLS的gnutls_pubkey_encrypt_data默认启用的是PKCS#1 v1.5填充(对应OpenSSL的RSA_PKCS1_PADDING),这就是加密输出格式不匹配的原因。
修改步骤
1. 指定OAEP填充模式
将加密函数的第二个参数从0改为GNUTLS_PKCS_OAEP,显式启用PKCS#1 OAEP填充:
const gnutls_datum_t input = { .data = (void *)spice.password, .size = strlen(spice.password) + 1 }; gnutls_datum_t out; // 替换第二个参数为GNUTLS_PKCS_OAEP,启用OAEP填充 if (gnutls_pubkey_encrypt_data(pubkey, GNUTLS_PKCS_OAEP, &input, &out) < 0) { gnutls_pubkey_deinit(pubkey); spice_disconnect_channel(channel); DEBUG_ERROR("gnutls_pubkey_encrypt_data failed"); return false; }
2. 释放GnuTLS分配的内存
gnutls_pubkey_encrypt_data会自动为out.data分配内存,使用完加密数据后必须调用gnutls_free释放,避免内存泄漏:
// 这里是你使用enc和rsaSize进行后续操作的代码 // ... // 操作完成后释放资源 gnutls_free(out.data); gnutls_pubkey_deinit(pubkey);
3. (可选)匹配非默认哈希算法
如果你的原始OpenSSL代码使用了SHA-256等非默认哈希算法的OAEP填充,需要在导入公钥后额外设置GnuTLS的哈希偏好:
if (gnutls_pubkey_import(pubkey, &pubData, GNUTLS_X509_FMT_DER) < 0) { // 错误处理 } // 设置SHA-256作为OAEP的哈希算法 if (gnutls_pubkey_set_preferred_hash(pubkey, GNUTLS_DIG_SHA256) < 0) { gnutls_pubkey_deinit(pubkey); spice_disconnect_channel(channel); DEBUG_ERROR("Failed to set preferred hash"); return false; }
验证
修改完成后,GnuTLS的加密输出就会和OpenSSL使用RSA_PKCS1_OAEP_PADDING的结果完全一致了。
内容的提问来源于stack exchange,提问作者Geoffrey
相关产品推荐
相关产品推荐

