我正在生成一个许可证密钥有效载荷,并使用私钥通过RSA对其进行加密,然后使用公钥对其进行解密,以在面向用户的软件中利用许可证有效载荷。我要加密而不是签名,因此我只需要向用户传递一个字符串,而不需要传递密钥和签名。
但是我在使用带有私钥加密的OAEP填充时遇到了麻烦:
require 'openssl'
padding = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
priv = OpenSSL::PKey::RSA.new 2048
pub = priv.public_key
# FIXME: Why can't I use OAEP padding with private key encryption?
data = 'customer:foo@example.com;allowances:25;users:5;locked:true;'
enc = priv.private_encrypt data, padding
dec = pub.public_decrypt enc, padding
puts dec == data
回复:https://repl.it/repls/LavishEarnestWifi。
运行此命令将引发错误:unknown padding type
。使用公钥加密可以使用OAEP,但不能使用私钥。但是,使用PKCS1填充有效。我以为使用PKCS1是不安全的,建议使用OAEP?我希望能够加密相同的有效负载并获得不同的许可证密钥,就像使用OAEP填充一样。
我在做什么错?这是个坏主意吗?
答案 0 :(得分:2)
是的,这是一件坏事。仅当使用针对签名生成的填充方案时,签名生成才被证明是安全的。实际上,即使它们经常使用相同的名称,用于签名生成和加密的PKCS#1 v1.5填充也是不同的。
您似乎正在寻找一种具有(部分)消息恢复的签名方案。那些不再使用了。原因之一是因为ECDSA签名比RSA签名小得多(ECC密钥大小是原来的两倍,对于非常安全的256位曲线,大约为64个字节)。
有几种签名生成方法可以指定here(ISO 9796)来进行消息恢复。这些有些陈旧且危险,特别是如果攻击者可以某种方式影响输入消息时。通常它们足够了。对于真正安全的方案,有[PSS提供消息恢复,正式称为EMSR-PSS,指定为in section 1.3 of the paper: PSS: Provably secure encoding method for digital signatures by Bellare and Rogaway。
不幸的是,Ruby似乎无法直接使用它们,因此您可能必须实现或链接到填充方案。就是说,由于OAEP也不可用,因此几乎没有取消资格。通常,我只是选择ECDSA,并将消息与较小的签名格式结合在一起。
请注意,私钥操作与RSA公钥操作完全不同。它们通常依赖于CRT参数。此外,而且可能更重要的是,它们必须被设计为保护私钥免受诸如边信道攻击之类的攻击。仅使用私钥而不是公钥不是一个好主意。
有关使用OAEP进行签名生成的讨论,请参见讨论here。有关使用私钥进行RSA加密是否等同于签名生成的信息,请参阅我自己的问题解答here。