最近在做开放平台项目,在编写SDK的时候用到签名验签功能,采用Sha256WithRSA
签名,具体流程是使用私钥生成签名,然后公钥进行验签。
现在把私钥签名的代码分享出来。
添加依赖
在Cargo.toml添加:
[dependencies]
# rsa库
rsa = "0.3.0"
# 加密库
rust-crypto = "^0.2"
# base64库
base64 = "0.12.3"
完整代码:
extern crate rsa;
extern crate crypto;
use rsa::{RSAPrivateKey, PaddingScheme};
use rsa::Hash;
use crypto::sha2::Sha256;
use crypto::digest::Digest;
use std::iter::repeat;
pub enum HashType {
Sha1,
Sha256
}
/// RSA签名
///
/// - content: 签名内容
/// - private_key: 私钥,PKCS#1
/// - hash_type: hash类型
///
/// # Examples
///
/// ```
/// use sdk::sign::{SignUtil, HashType};
///
/// let content = "123";
/// let private_key = "your private key";
/// let sign = SignUtil::rsa_sign(content, private_key, HashType::Sha256);
///
/// println!("sign:{}", sign);
/// ```
/// return: 返回base64字符串
pub fn rsa_sign(content: &str, private_key: &str, hash_type: HashType) -> String {
// 格式化私钥
let der_encoded = private_key
.lines()
.filter(|line| !line.starts_with("-"))
.fold(String::new(), |mut data, line| {
data.push_str(&line);
data
});
let der_bytes = base64::decode(der_encoded).expect("failed to decode base64 content");
// 获取私钥对象
let private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key");
// 创建一个Sha256对象
let mut hasher = Sha256::new();
// 对内容进行摘要
hasher.input_str(content);
// 将摘要结果保存到buf中
let mut buf: Vec<u8> = repeat(0).take((hasher.output_bits()+7)/8).collect();
hasher.result(&mut buf);
// 对摘要进行签名
let hash;
match hash_type {
HashType::Sha1 => hash = Hash::SHA1,
HashType::Sha256 => hash = Hash::SHA2_256
}
let sign_result = private_key.sign(PaddingScheme::PKCS1v15Sign {hash: Option::from(hash) }, &buf);
// 签名结果转化为base64
let vec = sign_result.expect("create sign error for base64");
base64::encode(vec)
}
// 测试
#[cfg(test)]
mod tests {
use crate::{HashType, rsa_sign};
#[test]
fn it_works() {
let content = "123";
let private_key = "MIICXAIBAAKBgQCHJlAPN+1dCbgc3HiahQkT2W/skecGWOCkSX4CPvEc8oIk6544\nxihEwShHnfrapiQdF2fndv5agrhg4FyOHheST42L5MnCk+4Km+mWm5GDvmFS7Sa2\naZ5o3regY0MUoJ7D74dYjE3UYFuTujAXiXjGpAwa9qOcKotov5LCkSfUeQIDAQAB\nAoGAB1cyw8LYRQSHQCUO9Wiaq730jPNHSrJW4EGAIz/XMYjv/fCgx0lnDEX4CbzI\nUGoz/bME4R721YRyXoutJ0h14/cGrt/TEn/TMI0xnISzJHr8VSlyBkQEdfO/W3LO\nqjs/UYq2Bz4+kJROJHreM+7d5hiIWLzLBlyI8cSU92ySmHECQQDwju2SoRu88kQP\n1qr4seZyKQa8DHTVyCoa6LtPLXyJsdgWgY4KyqJHwMUumEC2Zhhu833CR0ZXbfta\nuQDmwAVJAkEAj9M225jrPasaD5vPO7thxtEqgV4F/ZyNKH0Z8bDH27KaKkQ+8GMt\nkxwKVckZXs2bMvg/6tCiDZkWAxawNrvFsQJBANmTrPWOmpQPW9gnhYRjA9gFm33C\nlno2DT9BeQloTtgL7zKMA3lnRdg4VyCJvR48waS4vupVpR228D1iT5pl22ECQF1M\nJUzkcM0rPheb+h2EW1QOgWU0Keyvbj4ykO7gv3T78dezN6TWoUzJpsapUiTWeXPh\n6AyZ1FW/1bChOiP3QLECQGAbObmsYlN0bjzPYChwWYeYjErXuv51a44GZCNWinFw\nGGiHU9ZAqF8RzmBVW4htwj0j/Yry/V1Sp0uoP0zu3uA=";
let sign = SignUtil::rsa_sign(content, private_key, HashType::Sha256);
println!("sign:{}", sign);
}
}
注:私钥类型为PKCS#1
,并且去掉了-----BEGIN RSA PRIVATE KEY-----
开头和-----END RSA PRIVATE KEY-----
结尾
如果需要采用ShaWithRSA
,HashType换成Sha1即可
let sign = rsa_sign(content, private_key, HashType::Sha1);