2017-12-17 35 views

답변

2

C++에서 C++ ++ 라이브러리를 사용하여 RSA 숨은 서명을 간결하게 구현할 수 있습니까?

예. Crypto ++ 위키에는 RSA의 시각 장애인 서명 부분이 있습니다 (Raw RSA | RSA Blind Signature). 아래는 위키에서 가져온 코드입니다.

Crypto ++에는 시각 장애인 서명 클래스가 없습니다. 아래의 방법은 Blind Signatures에 설명 된 기본 알고리즘을 따릅니다. 그러나 위키피디아와 다른 점은 s(s'(x)) = x 교차 점검을 적용한 경우입니다. 교차 확인은 Chaum's original paper에 있었지만 위키 문서에서는 누락되었습니다. Chaum의 논문과 위키 백과의 두 번째 차이점은 아래의 코드가 m이 아닌 H(m)입니다. 그게 Rabin in 1979 때문입니다.

우리가 알고있는 한, 서명 체계를 다루는 표준은 없습니다. 표준화가 이루어지지 않아서 반드시 interop 문제가 발생할 것입니다. 예를 들어, 아래 코드는 SHA256을 사용하여 서명 할 메시지를 해시하는 반면 RSA Blind Signature Scheme for golang은 전체 도메인 해시를 사용합니다. Crypto.SE의 Is there a standard padding/format for RSA Blind Signatures?도 참조하십시오.

Usability of padding scheme in blinded RSA signature? 또는 RSA blind signatures in practice 당 패딩 기능을 먼저 적용 할 수 있습니다.

$ g++ blind.cxx ./libcryptopp.a -o blind.exe 
$ ./blind.exe 
Pub mod: b55dc5e79993680fh 
Pub exp: 11h 
Priv mod: b55dc5e79993680fh 
Priv exp: 1b4fc70ff2e97f1h 
Message: 736563726574h 
H(m): 2bb80d537b1da3e3h 
Random: 72dd6819f0fc5e5fh 
Blinded msg: 27a2e2e5e6f4fbfh 
Blind sign: 84e7039495bf0570h 
Check sign: 27a2e2e5e6f4fbfh 
Unblind sign: 61054203e843f380h 
Verify: 2bb80d537b1da3e3h 
Verified signature 
: 여기


#include "cryptlib.h" 
#include "integer.h" 
#include "nbtheory.h" 
#include "osrng.h" 
#include "rsa.h" 
#include "sha.h" 
using namespace CryptoPP; 

#include <iostream> 
#include <stdexcept> 
using std::cout; 
using std::endl; 
using std::runtime_error; 

int main(int argc, char* argv[]) 
{ 
    // Bob artificially small key pair 
    AutoSeededRandomPool prng; 
    RSA::PrivateKey privKey; 

    privKey.GenerateRandomWithKeySize(prng, 64); 
    RSA::PublicKey pubKey(privKey); 

    // Convenience 
    const Integer& n = pubKey.GetModulus(); 
    const Integer& e = pubKey.GetPublicExponent(); 
    const Integer& d = privKey.GetPrivateExponent(); 

    // Print params 
    cout << "Pub mod: " << std::hex << pubKey.GetModulus() << endl; 
    cout << "Pub exp: " << std::hex << e << endl; 
    cout << "Priv mod: " << std::hex << privKey.GetModulus() << endl; 
    cout << "Priv exp: " << std::hex << d << endl; 

    // For sizing the hashed message buffer. This should be SHA256 size. 
    const size_t SIG_SIZE = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount()); 

    // Scratch 
    SecByteBlock buff1, buff2, buff3; 

    // Alice original message to be signed by Bob 
    SecByteBlock orig((const byte*)"secret", 6); 
    Integer m(orig.data(), orig.size()); 
    cout << "Message: " << std::hex << m << endl; 

    // Hash message per Rabin (1979) 
    buff1.resize(SIG_SIZE); 
    SHA256 hash1; 
    hash1.CalculateTruncatedDigest(buff1, buff1.size(), orig, orig.size()); 

    // H(m) as Integer 
    Integer hm(buff1.data(), buff1.size()); 
    cout << "H(m): " << std::hex << hm << endl; 

    // Alice blinding 
    Integer r; 
    do { 
     r.Randomize(prng, Integer::One(), n - Integer::One()); 
    } while (!RelativelyPrime(r, n)); 

    // Blinding factor 
    Integer b = a_exp_b_mod_c(r, e, n); 
    cout << "Random: " << std::hex << b << endl; 

    // Alice blinded message 
    Integer mm = a_times_b_mod_c(hm, b, n); 
    cout << "Blind msg: " << std::hex << mm << endl; 

    // Bob sign 
    Integer ss = privKey.CalculateInverse(prng, mm); 
    cout << "Blind sign: " << ss << endl; 

    // Alice checks s(s'(x)) = x. This is from Chaum's paper 
    Integer c = pubKey.ApplyFunction(ss); 
    cout << "Check sign: " << c << endl; 
    if (c != mm) 
     throw runtime_error("Alice cross-check failed"); 

    // Alice remove blinding 
    Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n); 
    cout << "Unblind sign: " << s << endl; 

    // Eve verifies 
    Integer v = pubKey.ApplyFunction(s);  
    cout << "Verify: " << std::hex << v << endl; 

    // Convert to a string 
    size_t req = v.MinEncodedSize(); 
    buff2.resize(req); 
    v.Encode(&buff2[0], buff2.size()); 

    // Hash message per Rabin (1979) 
    buff3.resize(SIG_SIZE); 
    SHA256 hash2; 
    hash2.CalculateTruncatedDigest(buff3, buff3.size(), orig, orig.size()); 

    // Constant time compare 
    bool equal = buff2.size() == buff3.size() && VerifyBufsEqual(
     buff2.data(), buff3.data(), buff3.size()); 

    if (!equal) 
     throw runtime_error("Eve verified failed"); 

    cout << "Verified signature" << endl; 

    return 0; 
} 
건물의 결과와 프로그램을 실행하는 것입니다