最近在做開放平臺項目,在編寫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 = String::from("123");
/// let private_key = String::from(私鑰內容);
/// let sign = SignUtil::rsa_sign(content, private_key, HashType::Sha256);
///
/// println!("sign:{}", sign);
/// ```
/// return: 返回base64字符串
pub fn rsa_sign(content: String, private_key: String, 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.as_str());
// 將摘要結果保存到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 = String::from("123");
let private_key = String::from("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 = 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);