我的加密安全是openPGP / SMIME吗?

我正在尝试在更大的项目中编写一个简单的文件加密/解密。 由于许可证问题,我想避免使用libgpgme。 openPGP标准是复杂的项目时间框架。 我想用openssl做我的加密东西。

现在我实现了以下内容:

加密(pseude代码):

RAND_bytes(aes_key) RAND_bytes(aes_salt) EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (const unsigned char *)aes_salt, aes_key, sizeof(aes_key), 5, key, iv); 

然后我aes256我的数据

 EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, iv); 

然后我用RSA加密密钥和iv

 RSA_public_encrypt(flen, (unsigned char *)key, encryptedKey, rsa, RSA_PKCS1_PADDING ); RSA_public_encrypt(flen, (unsigned char *)iv, encryptedIV, rsa, RSA_PKCS1_PADDING ); 

然后我将128位密钥和iv保存在我文件的“顶部”(256Bytes标题)。

解密: – >读取前256字节(拆分为密钥和iv) – >解密密钥和iv用本地RSA私钥(当然RSA私钥不在文件中) – >使用密钥和iv解密数据

我对那段代码安全吗?

由于您EVP_SealInit()使用OpenSSL信封加密函数,因此您应该直接使用EVP_SealInit() / EVP_SealUpdate() / EVP_SealFinal()函数。 这些function负责生成对称密钥和IV,使用对称密钥加密数据并使用接收者RSA密钥加密对称密钥。

一旦你没有照顾的事情是真实性。 在CBC模式下,攻击者可能会对明文进行某些可预测的更改,即使他们无法读取它。 要检测到这一点,您应该计算加密消息上的HMAC(使用与加密相对应的单独对称密钥),或者对加密消息进行签名(例如,使用EVP_SignInit() / EVP_SignUpdate() / EVP_SignFinal() )。

由于这是一种新格式,因此应使用OAEP填充。 只需将RSA_PKCS1_PADDING更改为RSA_PKCS1_OAEP_PADDING 。 你实际上不需要加密IV(就我所知,它不会受到伤害,这可能会有所帮助)。

否则,只要RSA_size(rsa)==16 ,此方法就应该RSA_size(rsa)==16 。 当然,任何不能解密文件的人都不能知道私钥。

加密是一个易于使“工作”的主题 – 但很难保证安全。 如果有疑问(并且在毫无疑问时加倍),请选择一个广泛认可的标准并严格按照规范执行 。 用公共 – 私有算法加密密钥,然后将IV封装在理论上也是合理的,但我不确定加密IV的含义是什么,以及如果攻击者开始翻转会发生什么加密数据中的位? 等等。它看起来很合理,但我再次强烈建议您只是精确地实施已发布的规范。

我建议使用二进制传输编码实现S / MIME 。 S / MIME被认为是一个安全的规范,有些库实现了所有的硬件 ,最重要的是,你可以针对其他实现测试你的实现,以确保你没有超出规范。

一些观察:

  • EVP_BytesToKey函数用于从密码和salt创建密钥和初始化向量,而不是从随机数据创建。 它可以工作,但您也可以直接使用随机字节作为键和初始化向量。 (确保您使用的是安全的PRNG,我不确定RAND_bytes实际上做了什么。)

  • 初始化向量不需要是秘密的,CBC模式应该是非加密的IV安全的。 (但这并没有伤害。)

  • RSA加密看起来不错(但你可能想要使用另一个填充,正如David所说)。

  • 正如Serdalis所说,您还应该保护您的文件免受修改。 任何键控MAC都可以(最常见的是HMAC构建在密钥和散列函数上)。 加密后应用MAC。