「發送報文時,發送方用一個哈希函數從報文文本中生成報文摘要,而後用本身的私人密鑰對這個摘要進行加密,這個加密後的摘要將做爲報文的數字簽名和報文一塊兒發送給接收方,接收方首先用與發送方同樣的哈希函數從接收到的原始報文中計算出報文摘要,接着再用發送方的公用密鑰來對報文附加的數字簽名進行解密,若是這兩個摘要相同、那麼接收方就能確認該數字簽名是發送方的。 php
以上內容來自百度百科,數字簽名過程。ios
原本想着用rsa加解密和MD5就能夠實現數字簽名。查詢了網上的文章,通過本身嘗試。發現只能用公鑰加密,私鑰解密。這和數字簽名恰好是相反的,在CSDN裏發現也有人問過這個問題。這是加密函數RSAES_OAEP_SHA_Encryptor e(publicKey);這是解密函數RSAES_OAEP_SHA_Decryptor d(privateKey);dom
上面是用公鑰加密,私鑰解密的。和數字簽名好像是反過來的。到網上搜了搜,好像解決不了。我就本身去看了一下Crypto++rsa的wiki。本人的英語水平不行、用有道一邊猜一邊翻譯,明白了個大概吧。地址給你們https://www.cryptopp.com/wiki/RSA_Signature_Schemes#Downloads。能夠看一看,我也沒看明白多少就不給你們說那麼多了。方法教給你們,本身去看吧。函數
我把內容拷進來吧,不想戳進去的也能夠在這裏看。google
The following is a handful of sample programs demonstrating ways to create keys, sign messages and verify messages.加密
/////////////////////////////////////// // Pseudo Random Number Generator僞隨機數發生器 AutoSeededRandomPool rng; /////////////////////////////////////// // Generate Parameters 密鑰生成所需參數 InvertibleRSAFunction params; params.GenerateRandomWithKeySize(rng, 1536); /////////////////////////////////////// // Generated Parameters Integer n = params.GetModulus(); Integer p = params.GetPrime1(); Integer q = params.GetPrime2(); Integer d = params.GetPrivateExponent(); Integer e = params.GetPublicExponent(); /////////////////////////////////////// // Dump cout << "RSA Parameters:" << endl; cout << " n: " << n << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; cout << " d: " << d << endl; cout << " e: " << e << endl; cout << endl; /////////////////////////////////////// // Create Keys RSA::PrivateKey privateKey(params); RSA::PublicKey publicKey(params);
//帶有附錄的RSA簽名方案spa
AutoSeededRandomPool rng; InvertibleRSAFunction parameters; parameters.GenerateRandomWithKeySize(rng, 1536); RSA::PrivateKey privateKey(parameters); RSA::PublicKey publicKey(parameters); // Message string message = "Yoda said, Do or Do Not. There is no try."; // Signer object RSASS<PSS, SHA1>::Signer signer(privateKey); // Create signature space size_t length = signer.MaxSignatureLength(); SecByteBlock signature(length); // Sign message length = signer.SignMessage(rng, (const byte*) message.c_str(), message.length(), signature); // Resize now we know the true size of the signature
signature.resize(length); // Verifier object RSASS<PSS, SHA1>::Verifier verifier(publicKey); // Verify bool result = verifier.VerifyMessage((const byte*)message.c_str(), message.length(), signature, signature.size()); // Result if(true == result) { cout << "Signature on message verified" << endl; } else { cout << "Message verification failed" << endl; }
RSA簽名方案與附錄(過濾器)ssr
// Generate ot Load keys RSA::PrivateKey privateKey = ...; RSA::PublicKey publicKey = ...; // Message string message = "Yoda said, Do or Do Not. There is no try."; string signature, recovered; //////////////////////////////////////////////// // Sign and Encode RSASS<PSS, SHA1>::Signer signer(privateKey); StringSource ss1(message, true, new SignerFilter(rng, signer, new StringSink(signature) ) // SignerFilter ); // StringSource //////////////////////////////////////////////// // Verify and Recover RSASS<PSS, SHA1>::Verifier verifier(publicKey); StringSource ss2(message+signature, true, new SignatureVerificationFilter( verifier, new StringSink(recovered), SignatureVerificationFilter::THROW_EXCEPTION | SignatureVerificationFilter::PUT_MESSAGE ) // SignatureVerificationFilter ); // StringSource //////////////////////////////////////////////// // No exception - use recovered message ...
帶恢復的RSA機率簽名方案翻譯
//////////////////////////////////////////////// // Generate keys AutoSeededRandomPool rng; InvertibleRSAFunction params; params.GenerateRandomWithKeySize(rng, 1536); RSA::PrivateKey privateKey(params); RSA::PublicKey publicKey(params); // Signing RSASS<PSSR, SHA1>::Signer signer(privateKey); RSASS<PSSR, SHA1>::Verifier verifier(publicKey); // Setup byte message[] = "RSA-PSSR Test"; size_t messageLen = sizeof(message); //////////////////////////////////////////////// // Sign and Encode SecByteBlock signature(signer.MaxSignatureLength(messageLen)); size_t signatureLen = signer.SignMessageWithRecovery(rng, message, messageLen, NULL, 0, signature); // Resize now we know the true size of the signature signature.resize(signatureLen); //////////////////////////////////////////////// // Verify and Recover SecByteBlock recovered( verifier.MaxRecoverableLengthFromSignatureLength(signatureLen) ); DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0, signature, signatureLen); if (!result.isValidCoding) { throw Exception(Exception::OTHER_ERROR, "Invalid Signature"); } //////////////////////////////////////////////// // Use recovered message // MaxSignatureLength is likely larger than messageLength recovered.resize(result.messageLength); ...
RSA機率簽名方案與恢復(過濾)code
//////////////////////////////////////////////// // Generate or Load keys RSA::PrivateKey privateKey = ...; RSA::PublicKey publicKey = ...; //////////////////////////////////////////////// // Setup string message = "RSA-PSSR Test", signature, recovered; //////////////////////////////////////////////// // Sign and Encode RSASS<PSSR, SHA1>::Signer signer(privateKey); StringSource ss1(message, true, new SignerFilter(rng, signer, new StringSink(signature), true // putMessage for recovery ) // SignerFilter ); // StringSource //////////////////////////////////////////////// // Verify and Recover RSASS<PSSR, SHA1>::Verifier verifier(publicKey); StringSource ss2(signature, true, new SignatureVerificationFilter( verifier, new StringSink(recovered), THROW_EXCEPTION | PUT_MESSAGE ) // SignatureVerificationFilter ); // StringSource cout << "Verified signature on message" << endl;
RSA簽名方案(PKCS v1.5)
Though similar to RSA-SSA, RSASSA_PKCS1v15_SHA_Signer and RSASSA_PKCS1v15_SHA_Verifier uses PKCS v1.5 padding. The MD2 and MD5 variants of RSASSA_PKCS1v15_<Digest>_Signer and RSASSA_PKCS1v15_<Digest>_Verifier should not be used.
雖然相似於RSA-SSA,RSASSA_PKCS1v15_SHA_Signer和RSASSA_PKCS1v15_SHA_Verifier使用PKCS v1.5填充。 MD2和MD5的變種RSASSA_PKCS1v15_ <Verifier > _Signer和RSASSA_PKCS1v15_ <Verifier > _Verifier不該使用。
AutoSeededRandomPool rng; InvertibleRSAFunction parameters; parameters.GenerateRandomWithKeySize(rng, 1536); RSA::PrivateKey privateKey(parameters); RSA::PublicKey publicKey(parameters); // Message string message = "Yoda said, Do or Do Not. There is no try."; // Signer object RSASSA_PKCS1v15_SHA_Signer signer(privateKey); // Create signature space size_t length = signer.MaxSignatureLength(); SecByteBlock signature(length); // Sign message length = signer.SignMessage(rng, (const byte*) message.c_str(), message.length(), signature); // Resize now we know the true size of the signature signature.resize(length); // Verifier object RSASSA_PKCS1v15_SHA_Verifier verifier(publicKey); // Verify bool result = verifier.VerifyMessage((const byte*)message.c_str(), message.length(), signature, signature.size()); // Result if(true == result) { cout << "Signature on message verified" << endl; } else { cout << "Message verification failed" << endl; }
給定d和n的RSA簽名生成
Given Integers d and n rather than a RSA::PrivateKey, perform the following to create a signer object [1]. Attempting to use a RSA::PrivateKey by calling Initialize (i.e., not factoring n) will result in an exception [2].
給定的整數d和n,而不是一個RSA::PrivateKey,執行如下簽名者建立一個對象[1]。試圖使用RSA:PrivateKey經過調用初始化(i.e.,而不是考慮n)將致使異常[2]。
// Use InvertibleRSAFunction to factor 'n' InvertibleRSAFunction params; params.Initialize(n, e, d); RSA::PrivateKey(params); ...
If the public exponent has been misplaced, common values for the exponent are 3 (Microsoft CAPI/C#), 17 (Crypto++), and 65535 (Java).
給定e和n,RSA簽名驗證,
Given Integers e and n rather than a RSA::PublicKey, perform the following to create a verifier object.
RSASS<PSS, SHA>::Verifier verifier(n, e);
RSASS<PSS, SHA>::Verifier verifier; verifier.AccessKey().Initialize(n, e);
最後附上個人代碼:
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include "md5.h"
#include<iostream>
#include "pssr.h"
#include <hex.h>
#include "rsa.h"
#include "osrng.h"
using namespace CryptoPP;
#pragma comment(lib, "cryptlib.lib")
using namespace std;
bool md5(const string &src, string &digest)
{
Weak::MD5 md5;
StringSource(src, true,
new HashFilter(md5,
new HexEncoder(new StringSink(digest))
)
);
return true;
}
int main()
{
try
{
////////////////////////////////////////////////
// Generate keys
AutoSeededRandomPool rng;
InvertibleRSAFunction parameters;
parameters.GenerateRandomWithKeySize(rng, 1024);
RSA::PrivateKey privateKey(parameters);
RSA::PublicKey publicKey(parameters);
// Message
string message;
string signature,md5_message;
cout << "請輸入要簽名的內容:";
cin >> message;
cout << endl;
md5(message, md5_message); //將內容哈希
cout <<"將信息哈希爲摘要:"<<endl<<endl<< md5_message << endl << endl;
////////////////////////////////////////////////
// Sign and Encode
RSASS<PSS, SHA1>::Signer signer(privateKey);
StringSource(md5_message, true,
new SignerFilter(rng, signer,
new StringSink(signature)
) // SignerFilter
); // StringSource
cout << signature << endl<<endl<<endl;
////////////////////////////////////////////////
// Verify and Recover
RSASS<PSS, SHA1>::Verifier verifier(publicKey);
StringSource(md5_message + signature, true,
new SignatureVerificationFilter(
verifier, NULL,
SignatureVerificationFilter::THROW_EXCEPTION
) // SignatureVerificationFilter
); // StringSource
cout << "Verified signature on message" << endl;
} // try
catch (CryptoPP::Exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
以上內容僅供參考,初學者,如有錯誤請立即指正。