Rust RSA簽名算法(Sha256WithRSA)

最近在做開放平臺項目,在編寫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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章