2012-06-21 2 views
3

crypto ++ 라이브러리로 디지털 서명을 검증하는 방법은 무엇입니까?원시 RAW RSA 서명 확인 crypto ++ 라이브러리

입력 데이터는 다음

  • PUBLIC_KEY을 BASE64 인코딩 16 진수 문자열.
  • 공개 키의 공개 지수.
  • 서명은 16 진수 문자열입니다.

나는 개인 키 부분을 모른다. 이 테스트 기능을 작성했지만 "VerifierFilter : 디지털 서명이 유효하지 않습니다"라는 오류로 끝납니다.

여기의 키는 유효한 KeyPair에서 내보내집니다!

void rawRSAVerificationTest() 
{ 

// RSA 2048 digital signature verification 
try { 

    std::string pupKeyStr ("e0c3851114c758fb943a30ca8f9b4c7f506d52aa101c34ad5134f2cdbdddbef11ee6d1470d54caf3774d4d17d69488abf0b78beaebc046115cb29617610e98be3d5c303e19c14ae57ce0994701e3f24a628abf5c421777fb3c2b9b8b17f2a4cda4b9fd89e3c122085831c3e4502734bc3f3157d3ccd01198a8e3795f03661b55112acb69e8d5782bdf506bf5222777baf382d4d4bc2dd83e53af9236ed6e7a0fb8b5bb543ed4abbf478911bdc517e13e580b138f10f153eb2733ad60f3796e99b7d59f9abbd6666c69ba5ecc17a391424dc8ca3cf24a759c62d490056cda30265e11e316e7695028721c50eaf8e596161f0b59e4f598c85063bb3a847a5acb9d"); 
    //sha256 hashed data signature 
    std::string signatureStr = "d8d1df600d6781a9c030d9c697ec928eac34bf0670cf469f7fffb9c046deaee359b4e1218b419ff2589434510db8470ccf7abd28876a04b8d5a27293723e897f97a9367d2fbb379f8c52ec2a04cb71a06891a3f44d00e8bb9622b2038dbe6f29d0118203c372853ae09fb820702f1c16ee772998bd8a3db9e5127992a18d999fc422822caf0a82d9c12d6231605457ce651b0350b1e98584f9d4e6b973d6668df863d4b73784bbc00d8449918a0f049ddbeffc0d79579ade13a2d9012906b7ded7aae934bc54c5b85c924aee6627d66b7b200a23cd9b6a9c14650f1f9384e9ef9b90ac217ece026a1802bc0623150057ecd2b31f5f758e4ff866bb2e81d28368"; 

    //Chinese Remainder Theorem (CRT) 
    std::string pupExpStr ("0x10001"); 

    CryptoPP::AutoSeededRandomPool rng; 
    CryptoPP::RSA::PublicKey pubKeyRaw; 

    CryptoPP::Integer pup_key_cast(static_cast<CryptoPP::Integer> (pupKeyStr.c_str())); 
    CryptoPP::Integer pup_exp_cast(static_cast<CryptoPP::Integer> (pupExpStr.c_str())); 

    pubKeyRaw.Initialize(pup_key_cast, pup_exp_cast); 
    if (!pubKeyRaw.Validate(rng, 3)) 
    { 
     std::cout << "Error while public key validation" << std::endl; 
    } 

    CryptoPP::RSASS<CryptoPP::PSS, CryptoPP::SHA256>::Verifier verifier_sha256(pubKeyRaw); 


    CryptoPP::StringSource(signatureStr, true, 
     new CryptoPP::SignatureVerificationFilter( 
     verifier_sha256, NULL, 
     CryptoPP::SignatureVerificationFilter::THROW_EXCEPTION 
     ) // SignatureVerificationFilter 
     ); // StringSource 

} 
catch(CryptoPP::Exception& e) 
{ 
    std::cerr << "ERROR: " << e.what() << std::endl; 
} 
catch(...) 
{ 
    std::cerr << "ERROR: Unknown verify signature error" << std::endl; 
} 
} 

내가 놓친 것은 무엇입니까?

매우 도움이 될 것입니다. 미리 감사드립니다.

+0

"원시"는 무엇을 의미합니까? 서명을 생성하는 데 사용 된 RSA 서명 체계는 무엇입니까? PSS? –

+0

16 진수로 인코딩 된 모듈러스처럼 보입니다. 크기는 정확히 512 자입니다 (256 바이트 또는 2048 비트를 의미 함). "던지다"진술은 무엇을합니까? –

+0

RAW RSA : RSA 프리미티브와 함께 Crypto ++를 사용하여 암호화 및 암호 해독 작업 수행. – Diethard

답변

2

는 암호화 ++ 라이브러리에 디지털 서명을 검증 할 수 있는가? 당신이보기 위하여 어디에서 알고있는 경우

음, 하나는 간단합니다. RSA Signature Schemes에 암호화 ++ 위키에서 :

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; 
cout << "Message: " << recovered << endl; 

CryptoPP::RSASS<CryptoPP::PSS, CryptoPP::SHA256>::Verifier verifier_sha256(pubKeyRaw); 

몇 가지 질문 :

  • PSS (부록에 서명 방식) 또는 PSSR (서명 회복 계획)해야 하는가?
  • 예 : PKCS1v15와 같은 것이 확실합니까? 이 복구 방식 인 경우
  • signatureStr을 인코딩 진수의 시작이나 끝 부분에 서명입니까?

이 원래 Integer 초기화 아마 잘못이었다. Crypto ++는 0x 접두어가없고 h 접미사 (하나 또는 다른 접미사가 있어야 함)가 없기 때문에 문자열을 10 진수 정수로 파싱하려고 시도하지만 16 진 정수가 아닙니다.

당신은 접두사, 접미사를 추가하거나 바이트 배열 생성자를 사용해야합니다. 바이트 배열 생성자는 아래와 같습니다.

std::string pupKeyStr ("e0c3851114c758fb..."); 

string pupKeyBin; 
StringSource ss1(pupKeyStr, true, 
    new HexDecoder(
     new StringSink(pupKeyBin) 
    ) 
); 

CryptoPP::Integer pup_key_cast((unsigned char*)pupKeyBin.data(), pupKeyBin.size()); 

StringSource(signatureStr, true, ... 
... 

이 아마 잘못된 것입니다.

string signatureBin; 
StringSource ss1(signatureStr, true, 
    new HexDecoder(
     new StringSink(signatureBin) 
    ) 
); 

StringSource ss2(signatureBin, true, 
    new SignatureVerificationFilter(... 
    ... 

내가 PSSAPSSR을 모두 사용하여 이진 서명으로 코드를 시도 : 당신은 아마 뭔가를해야합니다. 어느 쪽도 효과가 없었다. 나는 또한 SignatureVerificationFilter's SIGNATURE_AT_BEGIN and SIGNATURE_AT_END으로 시도했다. 어느 쪽도 효과가 없었다. 그리고 SHA1RSASSA_PKCS1v15_SHA_Verifier의 조합을 시도했습니다. 아무것도 효과가 없습니다.

보유하고있는 것을 정확하게 확인할 수 있습니까?