如何解决如何使用Windows CryptoAPI生成SHA256withRSA签名?
我需要在Windows(以及 Delphi 或 c ++)中使用SHA256withRSA
算法(RSASSA-PKCS1-V1_5-SIGN
和SHA-256
哈希函数对某些数据进行签名)。我怎样才能做到这一点?我想使用Windows CryptoAPI。
这是我验证签名的方法:
function ALVerifyRSA256Signature(const aData: AnsiString; // bytes string
const aSignature: AnsiString; // bytes string
const aBase64PubKeyModulus: ansiString;
Const aBase64PubKeyExponent: ansiString): boolean;
{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
procedure _bigEndianToLittleEndian(var aArr: TBytes);
var B: Byte;
i,j: integer;
begin
J := Length(aArr) - 1;
i := low(aArr);
while i < J do begin
B := aArr[i];
aArr[i] := aArr[j];
aArr[j] := B;
Dec(j);
inc(i);
end;
end;
var pModulus: TBytes;
cbModulus: DWORD;
pExponent: TBytes;
cbExponent: DWORD;
dwExponent: Dword;
hProv: HCRYPTPROV;
cbKeyBlob: DWord;
pKeyBlob: Tbytes;
pPublicKey: PUBLICKEYSTRUC;
pRsaPubKey: RSAPUBKEY;
hRSAKey: HCRYPTKEY;
hHash: HCRYPTHASH;
pSignature: TBytes;
begin
//init pModulus / cbModulus
if not CryptStringToBinaryA(
PansiChar(aBase64PubKeyModulus),// pszString: LPCSTR;
length(aBase64PubKeyModulus),// cchString: DWORD;
CRYPT_STRING_BASE64,// dwFlags: DWORD;
nil,// pbBinary: pByte;
@cbModulus,// pcbBinary: PDWORD;
nil,// pdwSkip: PDWORD;
nil) then raiseLastOsError; // pdwFlags: PDWORD
setlength(pModulus,cbModulus);
if not CryptStringToBinaryA(
PansiChar(aBase64PubKeyModulus),// dwFlags: DWORD;
@pModulus[0],// pdwSkip: PDWORD;
nil) then raiseLastOsError; // pdwFlags: PDWORD
_bigEndianToLittleEndian(pModulus);
//init pExponent / cbExponent
if not CryptStringToBinaryA(
PansiChar(aBase64PubKeyExponent),// pszString: LPCSTR;
length(aBase64PubKeyExponent),// pbBinary: pByte;
@cbExponent,// pdwSkip: PDWORD;
nil) then raiseLastOsError; // pdwFlags: PDWORD
setlength(pExponent,cbExponent);
if not CryptStringToBinaryA(
PansiChar(aBase64PubKeyExponent),// dwFlags: DWORD;
@pExponent[0],// pdwSkip: PDWORD;
nil) then raiseLastOsError; // pdwFlags: PDWORD
_bigEndianToLittleEndian(pExponent);
if cbExponent > sizeof(dwExponent) then
raise Exception.CreateFmt('Wrong exponent (%s)',[aBase64PubKeyExponent]);
dwExponent := 0;
move(pExponent[0],dwExponent,cbExponent);
//acquire a handle to a particular key container
if (not CryptAcquireContextA(@hProv,// phProv: PHCRYPTPROV;
nil,// pszContainer: PAnsiChar;
nil,// pszProvider: PAnsiChar;
PROV_RSA_AES,// dwProvType: DWORD;
CRYPT_VERIFYCONTEXT)) then raiselastOsError; // dwFlags: DWORD
try
// create the pKeyBlob
// The data format is: PUBLICKEYSTRUC + RSAPUBKEY + key
cbKeyBlob := sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + cbModulus;
setlength(pKeyBlob,cbKeyBlob);
// Fill in the PUBLICKEYSTRUC
pPublicKey.bType := PUBLICKEYBLOB;
pPublicKey.bVersion := CUR_BLOB_VERSION; // Always use this value.
pPublicKey.reserved := 0; // Must be zero.
pPublicKey.aiKeyAlg := CALG_RSA_KEYX; // RSA public-key key exchange.
Move(pPublicKey,pKeyBlob[0],sizeof(PUBLICKEYSTRUC));
// Fill in the RSAPUBKEY
pRsaPubKey.magic := RSA1; // Public key.
pRsaPubKey.bitlen := cbModulus * 8; // Number of bits in the modulus.
pRsaPubKey.pubexp := dwExponent; // Exponent.
Move(pRsaPubKey,pKeyBlob[sizeof(PUBLICKEYSTRUC)],sizeof(RSAPUBKEY));
// Fill in the modulus
Move(pModulus[0],pKeyBlob[sizeof(PUBLICKEYSTRUC)+sizeof(RSAPUBKEY)],cbModulus);
// Now import the key.
if not CryptImportKey(hProv,// hProv: HCRYPTPROV;
@pKeyBlob[0],// const pbData: PBYTE;
cbKeyBlob,// dwDataLen: DWORD;
0,// hPubKey: HCRYPTKEY;
0,// dwFlags: DWORD;
@hRSAKey) then raiseLastOsError; // phKey: PHCRYPTKEY
try
//initiates the hashing of a stream of data.
if not (CryptCreateHash(hProv,// hProv: HCRYPTPROV;
CALG_SHA_256,// Algid: ALG_ID;
0,// hKey: HCRYPTKEY;
0,// dwFlags: DWORD;
@hHash)) then raiseLastOsError;
try
//adds data to a specified hash object.
if not (CryptHashData(hHash,// hHash: HCRYPTHASH;
pbyte(aData),// const pbData: PBYTE;
length(aData),// dwDataLen: DWORD;
0)) then raiseLastOsError; // dwFlags: DWORD
//verifies the signature
setlength(pSignature,length(aSignature));
Move(Pointer(aSignature)^,Pointer(pSignature)^,Length(aSignature));
_bigEndianToLittleEndian(pSignature);
if not CryptVerifySignatureA(hHash,// hHash: HCRYPTHASH;
@pSignature[0],// const pbSignature: PBYTE;
length(pSignature),// dwSigLen: DWORD;
hRSAKey,// hPubKey: HCRYPTKEY;
nil,// const sDescription: LPCSTR;
0) then begin // dwFlags: DWORD)
if HRESULT(GetLastError) = NTE_BAD_SIGNATURE then exit(False)
else raiseLastOsError;
end;
//everything is ok
Result := True;
finally
if not CryptDestroyHash(hHash) then raiseLastOsError;
end;
finally
if not CryptDestroyKey(hRSAKey) then raiseLastOsError;
end;
finally
if not CryptReleaseContext(hProv,0) then raiseLastOsError;
end;
end;
但是,就我而言,我需要使用此private_key签名一些数据:
"-----BEGIN PRIVATE KEY-----\xxxxxxxxxxxxxxxxxxx\n-----END PRIVATE KEY-----\n"
我该怎么办?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。