我使用makecert效用OpenSSL和MS的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
然後我轉換RootCATest.pvk到RootCATest.pem使用OpenSSL生成X509證書與私鑰。我提取公鑰:pubRootCATest.pem
我有一個小文件叫'味精'。 我使用SHA1簽署此文件。
openssl dgst -sha1 -sign c:\RootCATest.pem -out c:\openssl c:\msg
然後我想要使用MS CryptoAPI獲得相同的數字簽名。
這裏是我的代碼(注:這是理解概念,所以我不要隨意分配內存的代碼)
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。沒有它,當OpenSSL簽名爲128字節時,我會得到大小爲130字節的簽名。所以我認爲CRYPT_NOHASHOID應該在那裏。
- SwapBytes(...)我嘗試過,沒有它。在這兩種情況下,我的 都有與OpenSSL簽名完全不同的簽名。
對於進入簽名的數據以及簽名本身,有很多不同的格式。這是你必須正確的部分。 – 2011-12-20 22:09:04
現在,使用RSA_verify驗證此簽名,如果它是可驗證的,則它是相同的。 – doptimusprime 2013-04-11 05:23:35