SHA256withRSA是什么,它的作用和顺序是什么?

31

对于密码学和相关领域,我是一个完全的新手。我不想(也不需要)知道SHA256和RSA的细节。我“知道”它们的作用,但不知道它们是如何做到的,现在这已经足够。

我想知道“SHA256withRSA”算法(如果可以称之为算法)实际上是做什么的,以及是按照什么顺序进行的。例如,它是否使用SHA256哈希数据,然后使用RSA加密数据,或者反过来,或者其他什么方式?

我提出这个问题是因为我想要实现Java等效的操作:

Signature.getInstance("SHA256withRSA")
signature.initSign(privateKey); //privateKey == a key extracted from a .p12 file

我在iOS上使用Objective-C。 我似乎找不到能完全做到这一点的任何内容,因此我想问一下,我是否可以对数据进行哈希处理(SHA256),然后加密它(RSA)(或反之亦然),并获得相同的行为?

针对这种情况,建议采用什么解决方案?

谢谢!

编辑:我未提到我使用私钥签署数据,该私钥是通过执行以下操作获得的:

KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(new File(filename)), password.toCharArray());
PrivateKey privateKey = (PrivateKey)keystore.getKey(alias, password.toCharArray());

其中filename的示例为:"/somewhere/mykey.p12"。

1个回答

35

SHA256withRSA的定义

"SHA256withRSA"实现了PKCS#1 v1.5填充和模块指数运算,使用SHA256对数据进行哈希计算后采用正式名称RSASSA-PKCS1-v1_5

签名生成

签名生成的一般策略为:

  1. 对消息进行哈希处理;
  2. 对哈希值进行填充以生成签名;
  3. 使用OS2IP将前述结果转换为数字;
  4. 使用私钥指数和模数进行模块指数运算;
  5. 使用I2OSP将前述结果转换为八位字符串。

签名验证

签名验证的策略分为两个部分。

第一部分:

  1. 哈希处理;
  2. 使用与签名生成相同的方法对哈希值进行填充;

第一部分的结果是本地生成的填充哈希值(称为EM')。

第二部分:

  1. 使用OS2IP将签名转换为数字;
  2. 使用公钥指数和模数进行模幂运算;
  3. 使用I2OSP将上一个结果转换为八位字符串。

第二部分的结果是原始填充哈希(称为EM)。

最后,比较原始和本地填充哈希(EM和EM');如果比较成功,则签名验证成功。

注释

  • 从PKCS#1 v2.0开始,PSS方案被设计为提供一种非确定性方案,具有更好的填充安全证明。对于新协议,建议使用PSS方案,尽管PKCS#1 v1.5方案仍被认为是安全的。

  • 在签名生成期间进行模幂运算时,可能不使用私有指数;如果CRT参数存在,则通常使用中国剩余定理进行加速约4倍。

  • OS2IP通过将八位字符串(或字节数组)解释为静态大小的无符号大端值来将其转换为整数,I2OSP执行反向操作。如果运行时可以直接在二进制表示上执行大整数计算,则转换是隐式的(即根本不需要执行)。

  • 用于加密和签名生成的PKCS#1 v1.5填充是不同的,因此使用加密可能会导致错误的签名。

  • 另一种验证方法是从填充中提取哈希并执行哈希值比较。


iOS的 PKCS#1 v1.5

关于iOS中的填充,请参考Thomas Pornin的this answer。基本上,您应该创建SHA-256哈希值,前缀一个静态数据块(在PKCS#1规范中定义),然后使用kSecPaddingPKCS1来使用SecKeyRawSign

为了方便起见,以下是需要以十六进制表示法前缀的PKCS#1定义的数据块,用于SHA-256(在标准文档中可能很难找到,在第9.2节的注释中):

30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20

感谢您的详细回答!我忘了提到包含私钥的文件是.p12文件,并且据我所知使用PKCS12,这会有什么区别吗?(我将编辑我的问题以包含此信息) - Whyser
容器格式对签名不应该有影响,因此这是一个额外的问题。请检查 https://dev59.com/Rmkw5IYBdhLWcg3wQoSm 是否包含您需要的信息。 - Maarten Bodewes
谢谢!你回答了我提出的问题,我会接受你的答案。你提供的链接对我有所帮助,但我仍然不知道如何在obj-c中使用密钥来签名数据。有什么指导吗?或者我应该发起一个新的问题?再次感谢你! - Whyser
返回的密钥引用不是sign方法的第一个输入吗?如果这不是真的,那么请浏览一下可用的代码。当然,您始终可以提出新问题(尽管我不是iOS开发人员,所以可能无法回答自己)。 - Maarten Bodewes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接