签名算法之RSASSA-PKCS1-v1_5

  1. 什么是RSASSA-PKCS1-v1_5
  2. 算法使用过程
  3. 相关摘要算法
  4. 代码实现

什么是RSASSA-PKCS1-v1_5

分开来解释,首先是RSA,RSA加密算法是一种非对称加密算法,由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年一起提出的,RSA就是他们三人姓氏开头字母拼在一起组成的。

RSASSA(RSA Signature Scheme with appendix)RSA填充签名,而PKCS1(Public-Key Cryptography Standards)是一组公钥加密标准,由美国密码学研究所(RSA Laboratories)制定。PKCS1-v1_5是PKCS1的一个版本,它定义了使用RSA算法生成数字签名的格式和算法。

具体来说,PKCS1-v1_5定义了将摘要值填充为特定格式(如填充”00 01 FF FF FF … FF 00”)后使用RSA私钥进行加密生成数字签名的算法流程。

所以,RSASSA-PKCS1-v1_5算法就是使用RSA算法和PKCS1-v1_5标准生成数字签名的算法。

算法使用过程

该算法由两个部分组成:签名生成和签名验证。

在签名生成过程中,需要使用RSA私钥和待签名的信息的摘要值生成数字签名。这个过程包括以下步骤:

  1. 使用摘要函数计算待签名信息的摘要值。
  2. 对摘要值进行填充,使其满足一定的格式要求。
  3. 使用RSA私钥对填充后的摘要值进行加密,生成数字签名。

在签名验证过程中,需要使用RSA公钥和待验证的信息的摘要值来验证数字签名的有效性。这个过程包括以下步骤:

  1. 使用摘要函数计算待验证信息的摘要值。
  2. 对摘要值进行填充,使其满足与签名生成时相同的格式要求。
  3. 使用RSA公钥对数字签名进行解密,得到填充后的摘要值。

将解密后的填充后的摘要值与步骤1中计算得到的摘要值进行比较,如果相同,则证明数字签名是有效的。

相关摘要算法

RSASSA-PKCS1-v1_5需要搭配具体的Hash函数,目前最常用的是SHA-256SHA-384SHA-512,分别为它们取了不同的简称:

算法简称 对应算法
RS256 RSASSA-PKCS1-v1_5 using SHA-256
RS384 RSASSA-PKCS1-v1_5 using SHA-384
RS512 RSASSA-PKCS1-v1_5 using SHA-512

代码实现

一般编程语言都有比较成熟的RSASHA的实现,合起来就能实现对应的算法了。首先引用依赖:

# Cargo.toml
[dependencies]
sha2 = { version = "0.10.6", default-features = false, features = ["oid"] }
hex = "0.4.3"
rsa = "0.7.2"

接着就可以在代码中实践了,我在此处分别实践了RS256RS384RS512三种,将Hello World字符串进行签名运算,使用随机函数生成RSA算法所需的字节数组来生成RSA的私钥,然后输出16进制形式的签名字符串,并使用verify函数进行验证:

use rsa::RsaPrivateKey;
use rsa::pkcs1v15::{SigningKey, VerifyingKey};
use rsa::signature::{RandomizedSigner, Signature, Verifier};
use sha2::{Sha256, Sha384, Sha512};
use hex;


fn main() {
    // 准备一个线程安全的随机数生成器
    let mut rng = rand::thread_rng();

    // 定义私钥长度
    let bits = 2048;
    // 生成RSA私钥
    let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");

    // 需要进行签名的数据
    let data = b"Hello World";

    // RS256签名
    let signing_key: SigningKey<Sha256> = SigningKey::<Sha256>::new_with_prefix(private_key.clone());
    let verifying_key: VerifyingKey<Sha256> = (&signing_key).into();
    let signature = signing_key.sign_with_rng(&mut rng, data);
    let signature_string = hex::encode(signature.as_bytes());
    println!("RS256 String is: {}", signature_string);

    // RS256签名验证
    verifying_key.verify(data, &signature).expect("failed to verify");

    // RS384签名
    let signing_key: SigningKey<Sha384> = SigningKey::<Sha384>::new_with_prefix(private_key.clone());
    let verifying_key: VerifyingKey<Sha384> = (&signing_key).into();
    let signature = signing_key.sign_with_rng(&mut rng, data);
    let signature_string = hex::encode(signature.as_bytes());
    println!("RS384 String is: {}", signature_string);

    // RS384签名验证
    verifying_key.verify(data, &signature).expect("failed to verify");

    // RS512签名
    let signing_key: SigningKey<Sha512> = SigningKey::<Sha512>::new_with_prefix(private_key.clone());
    let verifying_key: VerifyingKey<Sha512> = (&signing_key).into();
    let signature = signing_key.sign_with_rng(&mut rng, data);
    let signature_string = hex::encode(signature.as_bytes());
    println!("RS512 String is: {}", signature_string);

    // RS512签名验证
    verifying_key.verify(data, &signature).expect("failed to verify");

}

看下输出的结果:

    Finished dev [unoptimized + debuginfo] target(s) in 0.18s
     Running `target/debug/examples/study_rs`
RS256 String is: 51440042bb6bb48d378edb8894667a08e96c640c0999c0e7074bd48fe2a80b71f2bd757ff4e50f8da9274d75ded0fbe8cafc840a6d0b7e58d9be4e5c9a14059b564993e0294a0de5c4edde8562e386eb8d9cec7fee82ae3c823c51943b65e665b458b5ba43c9dc7d9e5f529d90fe9c849624729b521f5e040c0e3b5ff98cba831ce2595225170538b496d3d103cf5bacdf9248db27fb93ad70c769ca695c86a745ee8b5af3c4befe33a1699658291092ca46f6f2d8f2ce23fac09b443fc77d6495a0e8418e90fa710b2aee1534d5797870ab6a981a7b385cbe4202bbbefdcea00ada66a36d365cc4165d5c731cab49ec13e86f0134366617003a1c3af1f374fb

RS384 String is: 7ad2e5afc1ea2222d2728bcba4f33f51a081f454dce30f5f7e9ab88ee3fdc497b1c0e33a6fddca38b3693ce41f50a2074562e19410c1e43a61485ad1f224d635d350cf51dc44d2e5085d3848188258e4133a7e41ff0aa6cac1a12ec3e38f2720616abb3936be898d6856c9328e49a078e0514b0d11514b5782149621a76d4bb22418de5fe61026b52277eecd1035bc6298ad72afbb122a6357af2216f5859640662b307ddce31a70da67adfa8c03bd8d68cebca6a7f76e1c302d68f2e0d396fdc5f442e11cc42e848f5fabbcc30ab0fce6d5ffffa8bc21fdd0abeb379a43ddf5e930e0ed047dc64b5eef9c9195d40cb92d3e93edf92d4949e6210203144ae3fd

RS512 String is: 9d6095e6a7391bee093e0ee6841529362e7ac4f3f27ebb952f97b4fa520bd6b6c448bd4c678f21334a6f01374d0f0e7eecc1bc6ac0f12e6493cc3756fcf57a376dd05cc3aa27336808882f2db448fc3a63454dd4398eac8d21549e5b1040b5604acfb8ebb4ec27f4492a56526548c4aba0a9d552cd8e79422e5f600ad812e4dcc98e899c13cfedfdac0ad094cd92b2bedbfcf8861f29742a035e5c63d57f8b11ee5a464e7afb10121b23ff4078df4f6a910e1828203b8ca4d59b85068693274495619e552b5bc6fbb52905be1318014e9aa5b0b85107f7fc96dcd2eec7c5427b087317493a91b30bbd024254f0bb741b43e964d510dbca66b18655755d2dfb23

源代码请参考GitHub仓库


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jimmyseraph@testops.vip

×

喜欢就点赞,疼爱就打赏