विफल रहता है मैं OpenSSL libeay32.dll का उपयोग करके डेल्फी में SHA256 हस्ताक्षर और सत्यापन को लागू करने का प्रयास कर रहा हूं। यही कारण है कि अब तक इतना आसानडेल्फी में ओपनएसएसएल के साथ SHA256 हस्ताक्षर सत्यापित करना
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem
: की वजह एक पहला कदम में मेरे द्वारा बनाए गए एक आरएसए 2048-बिट कुंजी जोड़ी निम्नलिखित OpenSSL का उपयोग कर आदेशों।
function TSignSHA256.ReadKeyFile(aFileName : String; aType : TKeyFileType) : pEVP_PKEY;
var locFile : RawByteString;
locBIO : pBIO;
begin
locFile := UTF8Encode(aFileName);
locBIO := BIO_new(BIO_s_file());
try
BIO_read_filename(locBIO, PAnsiChar(locFile));
result := NIL;
case aType of
kfPrivate : result := PEM_read_bio_PrivateKey(locBIO, result, nil, nil);
kfPublic : result := PEM_read_bio_PUBKEY(locBIO, result, nil, nil);
end;
finally
BIO_free(locBIO);
end;
end;
कि के रूप में अच्छी तरह से काम करने के लिए लग रहा था: अगले कदम के लिए मैंने किया था एक समारोह है कि पीईएम फाइलों से सार्वजनिक और निजी कुंजियों को पढ़ने में सक्षम था बनाने गया था। तो मैं कुछ संकेत प्रक्रिया को लागू किया:
procedure TSignSHA256.Sign;
var locData : RawByteString;
locKey : pEVP_PKEY;
locCtx : pEVP_MD_CTX;
locSHA256 : pEVP_MD;
locSize : Cardinal;
locStream : TBytesStream;
begin
locKey := ReadKeyFile('private.pem', kfPrivate);
locData := ReadMessage('message.txt');
locCtx := EVP_MD_CTX_create;
try
locSHA256 := EVP_sha256();
EVP_DigestSignInit(locCtx, NIL, locSHA256, NIL, locKey);
EVP_DigestSignUpdate(locCtx, PAnsiChar(locData), Length(locData));
EVP_DigestSignFinal(locCtx, NIL, locSize);
locStream := TBytesStream.Create;
try
locStream.SetSize(locSize);
EVP_DigestSignFinal(locCtx, PAnsiChar(locStream.Memory), locSize);
WriteSignature('message.sig', locStream.Bytes, locSize);
finally
FreeAndNIL(locStream);
end;
finally
EVP_MD_CTX_destroy(locCtx);
end;
end;
आप देख सकते हैं प्रक्रिया, एक फ़ाइल message.txt बुलाया पढ़ रही है हस्ताक्षर की गणना और message.sig है कि sig भंडारण। अगर मैं चलाने निम्नलिखित OpenSSL परिणाम कमान सत्यापित ठीक है:
openssl dgst -sha256 -verify public.pem -signature message.sig message.txt
तो यह की तरह मेरे हस्ताक्षर करने की प्रक्रिया भी सही काम कर रहा है लगता है। इसलिए मैंने अंत में एक सत्यापन प्रक्रिया लागू की:
function TSignSHA256.Verify : Boolean;
var locData : RawByteString;
locSig : TArray<Byte>;
locKey : pEVP_PKEY;
locCtx : pEVP_MD_CTX;
locSHA256 : pEVP_MD;
locSize : Cardinal;
locStream : TBytesStream;
begin
locKey := ReadKeyFile('public.pem', kfPublic);
locData := ReadMessage('message.txt');
locSig := ReadSignature('message.sig');
locSize := Length(locSig);
locCtx := EVP_MD_CTX_create;
try
locSHA256 := EVP_sha256();
EVP_DigestVerifyInit(locCtx, NIL, EVP_sha256(), NIL, locKey); //Returns 1
EVP_DigestVerifyUpdate(locCtx, PAnsiChar(locData), Length(locData)); //Returns 1
locStream := TBytesStream.Create(locSig);
try
result := (EVP_DigestVerifyFinal(locCtx, PAnsiChar(locStream.Memory), locSize) = 1); //Returns false! WHY???
finally
FreeAndNIL(locStream);
end;
finally
EVP_MD_CTX_destroy(locCtx);
end;
end;
जैसा कि आप देख सकते हैं कि मैंने इस प्रक्रिया को ठीक उसी तरह कार्यान्वित किया जैसा मैंने हस्ताक्षर प्रक्रिया को लागू किया था। दुर्भाग्य से इसका परिणाम झूठा है। त्रुटि OpenSSL द्वारा लौटाए गए कोड
error04091077:lib(4):func(145):reason:(119)
कि lib आरएसए में किसी त्रुटि के लिए अनुवाद है, int_rsa_verify कार्य करते है, कारण गलत हस्ताक्षर लंबाई। मैंने Google की खोज की लेकिन मुझे उस त्रुटि के बारे में कोई उपयोगी जानकारी नहीं मिली। मैंने ओपनएसएसएल स्रोतों को समझने की भी कोशिश की, लेकिन मैं सी में गहराई से नहीं हूं और ऐसा लगता है कि इसमें उम्र लग सकती है जब तक कि मैं इसे समझने में सक्षम न हो।
मेरी व्यक्तिगत भावना यह है कि मैंने सार्वजनिक कुंजी को पढ़ने में कुछ गलत किया। लेकिन यह केवल एक भावना है और मुझे नहीं पता कि मैं इसे अलग तरीके से कैसे कर सकता हूं। मेरा दूसरा अनुमान यह होगा कि मैंने सत्यापन प्रक्रिया में संदर्भ को गलत बनाने में कुछ गलत किया है। लेकिन मुझे कोई संकेत नहीं है कि यह क्या हो सकता है।
हस्ताक्षर सत्यापन विफल क्यों है?
आप याद आती है त्रुटि हैंडलिंग, 'अगर EVP_DigestVerifyInit' जाँच और' EVP_DigestVerifyUpdate' सफल होने के साथ शुरू (वापसी मूल्यों की जाँच) – Remko
सी [ ईवीपी हस्ताक्षर और सत्यापन] (http://wiki.openssl.org/index.php/EVP_Signing_and_Verifying) ओपनएसएसएल विकी पर। यह आपको उदाहरण देता है जो बॉक्स से बाहर काम करता है। – jww
@Remko: मैंने अभी पठनीयता के लिए त्रुटि को संभालने में त्रुटि छोड़ी है। EVP_DigestVerifyInit और EVP_DigistVerify दोनों रिटर्न 1 अपडेट करें जिसका अर्थ सफलता है। मैंने इसे और अधिक स्पष्ट करने के लिए अपना कोड संपादित किया है। –