OpenSSL VPN Serveurs de messagerie |
OpenSSL/Rsa-cryptoapi-openssl-signLa signature avec des clefs asymétriques est presque identique au chiffrement sauf que l'utilisation des clefs est inversée (la clef privée signe et la clef publique vérifie) et que windows n'accepte de chiffrer qu'un hash. création des clefs
Les fichiers privateKeyMS.bin et publicKeyMS.bin transformés en Base64 deviennent respectivement les variables PVK et PUB du code ci-dessous. génération et vérification de la signaturevoid reverse(LPBYTE pBuffer,DWORD& dwLen) { DWORD i; BYTE ctmp; for(i = 0; i < dwLen/2; i++) { ctmp = pBuffer[i]; pBuffer[i] = pBuffer[dwLen - 1 - i]; pBuffer[dwLen - 1 - i] = ctmp; } } void dump(TCHAR *dest,BYTE* pBuffer,DWORD& dwSize) { FILE* file; _tfopen_s(&file,dest,TEXT("wb")); fwrite(pBuffer,sizeof(BYTE),dwSize,file); fclose(file); } int signcheck() { TCHAR szPub[]= _T("BgIAAACkAABSU0ExAAQAAAEAAQClA7b53n9m6jzweqDdYBS+HekcQmc1QIW/tgKzma8Z0WWiMEkw7UQH") _T("OAnqcFY1sjLMt2q3plFkEnN+7udIkBbkEgMSJDgF/jAwmKPe6cNf6+69r/OlkTfrNC2lq9+ArOvsAtti") _T("nZNp5njq3nubWacKGZGiSPQVqENmWMQktD2dwg=="); TCHAR szPriv[]= _T("BwIAAACkAABSU0EyAAQAAAEAAQClA7b53n9m6jzweqDdYBS+HekcQmc1QIW/tgKzma8Z0WWiMEkw7UQH") _T("OAnqcFY1sjLMt2q3plFkEnN+7udIkBbkEgMSJDgF/jAwmKPe6cNf6+69r/OlkTfrNC2lq9+ArOvsAtti") _T("nZNp5njq3nubWacKGZGiSPQVqENmWMQktD2dwoFf41MHhZV8MER35ap07lff1WgdBrLN8zh2SuAxJdMw") _T("69FsFqR9SFUno/b79MUMZCllI+MQealbJT2pHLnP2OMlNrQ9/S64L1maPshFQplacjSY8kuUoPq8iBtl") _T("Dqlq49L5OliRDp5kBh0Fqs0RX7DxOSbDvFpJZ0mRpqLyOKnaAdVbIHLGIwpFSMKN2C4hSfKlLsPPpNwt") _T("mbS12f/UgPu6eR29jEbkRvEPXQG9Z+LnKn7ju9jne6CHotUEG9QB0TmpI+4K9dMGQn46Wf1AFl7vE+s2") _T("MFN4BzVHEIGme/cvrI0prez5C/apixGQB0o+Ge1GznRs7o+8G1xZfFimWh1jPwboiZPpsdk6Y9tbkOA+") _T("GJ8FtEn9bgHIv5joIbElhBz5amMSbYI9cdYzhPFBWJOVubBWyRhMt3ph4uRY1xgfAWpxrq0yal7Vc4Zd") _T("MAD85Rw7x2XUeoMWidxfpeQtdChLOTdbVkm1ZFbEFY5TjFQs/EkBfBG5puKtNnW6wqrLoBhScFzC6M6q") _T("5mG5oqH0GlsD7dXD6kYaC2Osl64tfvkSY8LfvNsnjQs3MUrhXA9+f0X4DS7fKvjX0AD/7jsU8ls="); HCRYPTPROV hProv=NULL; HCRYPTKEY hPublicKey,hPrivateKey; DWORD dwPublicKeySize=0,dwPrivateKeySize=0; BYTE *pbPublicKey,*pbPrivateKey; DWORD dwSignSize=0; BYTE *pbSign; HCRYPTHASH hHash; DWORD dwFlags=0; CryptStringToBinary(szPub,0,CRYPT_STRING_BASE64,NULL,&dwPublicKeySize,0,0); pbPublicKey = (BYTE*)malloc(dwPublicKeySize); CryptStringToBinary(szPub,0,CRYPT_STRING_BASE64,pbPublicKey,&dwPublicKeySize,0,0); CryptStringToBinary(szPriv,0,CRYPT_STRING_BASE64,NULL,&dwPrivateKeySize,0,0); pbPrivateKey = (BYTE*)malloc(dwPrivateKeySize); CryptStringToBinary(szPriv,0,CRYPT_STRING_BASE64,pbPrivateKey,&dwPrivateKeySize,0,0); BYTE* pbStream=(BYTE*)"here is the text you would like to sign"; DWORD dwStreamSize=strlen((char*)pbStream); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags); CryptCreateHash(hProv,CALG_SHA1, 0, 0, &hHash); CryptHashData(hHash,pbStream,dwStreamSize,0); BYTE bHash[20]={0}; DWORD dwHashLength = 20; CryptGetHashParam(hHash,HP_HASHVAL,bHash,&dwHashLength ,0); CryptImportKey(hProv,pbPrivateKey,dwPrivateKeySize,0,CRYPT_EXPORTABLE,&hPrivateKey); if(!CryptSignHash(hHash,AT_KEYEXCHANGE, NULL,0, NULL, &dwSignSize)) goto checksignend; pbSign = (BYTE*)malloc(dwSignSize); CryptSignHash(hHash,AT_KEYEXCHANGE, NULL,CRYPT_NOHASHOID, pbSign, &dwSignSize); reverse(pbSign,dwSignSize); dump(_T("C:\\text.sign"),pbSign,dwSignSize); reverse(pbSign,dwSignSize); // let's do a check CryptImportKey(hProv,pbPublicKey,dwPublicKeySize,0,CRYPT_EXPORTABLE,&hPublicKey); if(!CryptVerifySignature(hHash, pbSign, dwSignSize,hPublicKey,NULL,0)) goto checksignend; printf("OK"); checksignend: if(hHash) CryptDestroyHash(hHash); if(hProv) CryptReleaseContext(hProv, 0); if(pbSign) delete pbSign; if(pbPrivateKey) delete pbPrivateKey; if(pbPublicKey) delete pbPublicKey; return 0; } le fichier text.sign contient la signature du message pbStream, vérifions cela
Ce qui correspond bien au SHA1 de ce fichier contenant les mêmes données
Une méthode est spécialement prévue pour checker une signature, mais elle ne semble pas fonctionner avec openssl 1.0.0
|