मैं makecert उपयोगिताOpenSSL और एमएस CryptoAPI: विभिन्न डिजिटल हस्ताक्षर
makecert -n "CN=RootCATest" -r -sv RootCATest.pvk RootCATest.cer
makecert -sk MyKeyName -iv RootCATest.pvk -n "CN=tempCert" -ic RootCATest.cer -sr currentuser -ss my -sky signature —pe
तब मैं OpenSSL साथ RootCATest.pem को RootCATest.pvk परिवर्तित का उपयोग कर निजी कुंजी के साथ X509 प्रमाणपत्र बनाया था। और मैंने सार्वजनिक कुंजी निकाली: pubRootCATest.pem
मेरे पास 'msg' नामक छोटी फ़ाइल है। और मैं SHA1 का उपयोग करके इस फ़ाइल पर हस्ताक्षर करता हूं।
openssl dgst -sha1 -sign c:\RootCATest.pem -out c:\openssl c:\msg
फिर मैं एमएस क्रिप्टोएपीआई का उपयोग कर एक ही डिजिटल हस्ताक्षर प्राप्त करना चाहता हूं। (: इस अवधारणाओं को समझने के लिए तो मैं मुक्त आबंटित स्मृति नहीं है कोड है नोट)
void SwapBytes(BYTE *pv, int n)
{
BYTE *p = pv;
int lo, hi;
for(lo=0, hi=n-1; hi>lo; lo++, hi--)
{
BYTE tmp=p[lo];
p[lo] = p[hi];
p[hi] = tmp;
}
}
void sign()
{
FILE *file;
BYTE *msg;
int msg_size;
HCRYPTPROV hProv;
HCERTSTORE hStore;
PCCERT_CONTEXT pCert;
DWORD dwKeySpec;
BOOL fCallerFreeProv;
BYTE *pSignature;
DWORD sigLen;
// Read message bytes from file
file = fopen("c:\\msg", "r");
fseek(file, 0, SEEK_END);
msg_size = ftell(file);
fseek(file, 0, SEEK_SET);
msg = new BYTE[msg_size];
fread(msg, sizeof(BYTE), msg_size, file);
fclose(file);
hStore = CertOpenSystemStore(NULL, "My");
pCert = CryptUIDlgSelectCertificateFromStore(hStore, NULL, NULL, NULL, 0, 0, NULL);
CryptAcquireCertificatePrivateKey(pCert, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hProv, &dwKeySpec, &fCallerFreeProv);
PrintCryptoProviderName(hProv); // prints Microsoft Strong Cryptographic Provider
ALG_ID hashAlgId = CALG_SHA1;
HCRYPTHASH hHash;
CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
CryptHashData(hHash, msg, msg_size, 0);
CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &sigLen);
pSignature = new BYTE[sigLen];
CryptSignHash(hHash, dwKeySpec, NULL, CRYPT_NOHASHOID, pSignature, &sigLen);
SwapBytes(pSignature, sigLen); // Here i reverse byte order as I read that MS CryptoAPI uses reversed byte order
// Write signature bytes to file
file = fopen("c:\\CryptSignHash", "w");
fwrite(pSignature, sizeof(BYTE), sigLen, file);
fclose(file);
}
उत्पादन के रूप में मैं हस्ताक्षर OpenSSL द्वारा किए गए हस्ताक्षर से बिल्कुल अलग मिल
यहाँ मेरी कोड है। मैं एक ही हस्ताक्षर कैसे प्राप्त कर सकता हूं?
जैसा कि मैंने पर विचार कुछ क्षण ध्यान देने के लिए देखते हैं:
- मेरे msg_size फ़ाइल आकार के समान है। तो यह संकेत पर बाइट्स की संख्या है। कुछ साइटों पर मैंने बाइट सरणी में एक नल बाइट जोड़ने के लिए सिफारिशें देखीं। क्या मुझे वास्तव में इस तरह के मामले में इसकी ज़रूरत है?
- ध्वज CRYPT_NOHASHOID। इसके बिना मुझे आकार 130 बाइट्स का हस्ताक्षर मिलता है, जब ओपनएसएसएल द्वारा हस्ताक्षर किए गए हस्ताक्षर 128 बाइट होते हैं। तो मुझे लगता है कि CRYPT_NOHASHOID वहां होना चाहिए।
- स्वैपबाइट्स (...) मैंने इसके साथ और इसके बिना प्रयास किया। और दोनों मामलों में मैं में ओपनएसएसएल हस्ताक्षर के लिए बिल्कुल अलग हस्ताक्षर हैं।
हस्ताक्षर में हस्ताक्षर करने के साथ-साथ हस्ताक्षर में दोनों डेटा के लिए कई अलग-अलग प्रारूप हैं। यह वह हिस्सा है जिसे आपको सही होना होगा। –
अब, इस हस्ताक्षर को सत्यापित करने के लिए RSA_verify का उपयोग करें और यदि यह सत्यापित है, तो यह वही है। – doptimusprime