最近在做开放平台项目,在编写SDK的时候用到签名验签功能,采用
现在把私钥签名的代码分享出来。
添加依赖
在Cargo.toml添加:
1 2 3 4 5 6 7 | [dependencies] # rsa库 rsa = "0.3.0" # 加密库 rust-crypto = "^0.2" # base64库 base64 = "0.12.3" |
完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 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); } } |
注:私钥类型为
如果需要采用
1 | let sign = rsa_sign(content, private_key, HashType::Sha1); |