OpenSSL VPN Serveurs de messagerie |
OpenSSL/Rsa-cryptoapi-opensslOpenSSL.Rsa-cryptoapi-openssl HistoryHide minor edits - Show changes to markup Changed line 12 from:
// longueur de la clé 1024 = 1024 déplacés de 16 bits vers la gauche soit to:
// longueur de la clé 1024 = 1024 << 16 Added lines 1-185:
Les structures de stockage de Microsoft ont la particularité de ne pas être chiffrées et d'être au format little-endian contrairement à OpenSSL qui travaille en big-endian. Le résultat est que toutes les structures doivent être inversées lors du passage d'un monde à l'autre, heureusement depuis la version 0.9.8h des options non documentées ont été ajoutées aux commandes OpenSSL pour faciliter l'interopérabilité. Quelques exemples d'utilisation des librairies CryptoAPI création d'une clé asymétrique (:source lang=C :) // longueur de la clé 1024 = 1024 déplacés de 16 bits vers la gauche soit
void dump(TCHAR *dest,BYTE* pBuffer,DWORD& dwSize) { FILE* file; file = _tfopen(dest,TEXT("wb")); fwrite(pBuffer,sizeof(BYTE),dwSize,file); fclose(file); } int cipherdecipher() { DWORD dwFlags = 0; HCRYPTPROV hProv=NULL; HCRYPTKEY hPrivateKey; BYTE* pbPublicKeyBlob=NULL,*pbPrivateKeyBlob=NULL; DWORD dwPublicKeyBlobLen=0,dwPrivateKeyBlobLen=0; DWORD dwBlockLen=0,dwBlockSize=0; DWORD dwDataLen; BYTE *pbBuffer; DWORD dwBufferSize; CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags); // create RSA keys CryptGenKey(hProv, CALG_RSA_KEYX, KEYLENGTH | CRYPT_EXPORTABLE, &hPrivateKey); //export public key CryptExportKey(hPrivateKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwPublicKeyBlobLen); pbPublicKeyBlob = (BYTE*) malloc(dwPublicKeyBlobLen); CryptExportKey(hPrivateKey, NULL, PUBLICKEYBLOB, 0, pbPublicKeyBlob, &dwPublicKeyBlobLen); dump(_T("c:\\tmp\\pub.rsa"),pbPublicKeyBlob,dwPublicKeyBlobLen); //export private key CryptExportKey(hPrivateKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwPrivateKeyBlobLen); pbPrivateKeyBlob = (BYTE*) malloc(dwPrivateKeyBlobLen); CryptExportKey(hPrivateKey, NULL, PRIVATEKEYBLOB, 0, pbPrivateKeyBlob, &dwPrivateKeyBlobLen); dump(_T("c:\\tmp\\priv.rsa"),pbPrivateKeyBlob,dwPrivateKeyBlobLen); // get the cipher block length dwDataLen=sizeof(dwBlockLen); CryptGetKeyParam(hPrivateKey, KP_BLOCKLEN, (LPBYTE)&dwBlockLen,&dwDataLen,0); dwBlockSize = dwBlockLen/8; pbBuffer = (BYTE*) malloc(dwBlockSize); dwBufferSize = dwBlockSize-11; //padding PKCS #1 v1.5 for(UINT i =0; i<dwBufferSize; i++){pbBuffer[i] = i+32;} CryptEncrypt(hPrivateKey, NULL, FALSE, 0, pbBuffer, &dwBufferSize, dwBlockSize); dump(_T("c:\\tmp\\cipher.bin"),pbBuffer,dwBufferSize); CryptDecrypt(hPrivateKey, NULL, FALSE, 0, (BYTE *)pbBuffer, &dwBufferSize); free(pbBuffer); free(pbPrivateKeyBlob); free(pbPublicKeyBlob); CryptDestroyKey(hPrivateKey); CryptReleaseContext(hProv,0); return 0; } (:sourcend:) Trois fichiers ont été créés: pub.rsa, priv.rsa et cipher.bin. La clef privée est capable de coder/décoder. Les fichiers devront être transformés en base64 pour être réintroduits dans les codes par la commande ci-dessous
chiffrement avec la clé publique (:source lang=C :) int simplecipher() { TCHAR szPub[]=_T("BgIAAACkAABSU0ExAAQAAAEAAQCxDs+RugWaFnQVMdZhirCBxQ5b2bpJtk24B6nediR933O2x9GynHDJ/WUPDnBuPcsw1JCZhsb0P2QUs9KU+iV2P7rJn2dREEjOJ82bN/Y6t4mp65JrOXdFhgtJPG9YbRcOQKNftnqr/OrwxjQcok9T63vaTgR+7JXuir3KFB5PrA=="); DWORD dwFlags = 0; HCRYPTPROV hProv=NULL; HCRYPTKEY hPublicKey; DWORD dwPubKeySize=0; BYTE* pbPubKey; DWORD dwBlockLen=0,dwDataLen=0; BYTE *pbBuffer; DWORD dwBufferSize; DWORD dwBlockSize=0; CryptStringToBinary(szPub,0,CRYPT_STRING_BASE64,NULL,&dwPubKeySize,0,0); pbPubKey = (BYTE*)malloc(dwPubKeySize); CryptStringToBinary(szPub,0,CRYPT_STRING_BASE64,pbPubKey,&dwPubKeySize,0,0); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags); CryptImportKey(hProv,pbPubKey,dwPubKeySize,0,CRYPT_EXPORTABLE,&hPublicKey); dwDataLen=sizeof(dwBlockLen); CryptGetKeyParam(hPublicKey, KP_BLOCKLEN, (LPBYTE)&dwBlockLen,&dwDataLen,0); dwBlockSize = dwBlockLen/8; pbBuffer = (BYTE*) malloc(dwBlockSize); dwBufferSize = dwBlockSize-11; //padding PKCS #1 v1.5 for(UINT i =0; i<dwBufferSize; i++){pbBuffer[i] = i+32;} CryptEncrypt(hPublicKey, NULL, FALSE, 0, pbBuffer, &dwBufferSize, dwBlockSize); dump(_T("c:\\tmp\\cipher.bin"),pbBuffer,dwBufferSize); free(pbPubKey); free(pbBuffer); CryptDestroyKey(hPublicKey); CryptReleaseContext(hProv,0); return 0; } (:sourcend:) déchiffrement avec la clef privée (:source lang=C :) int simpledecipher() { TCHAR szPriv[]=_T("BwIAAACkAABSU0EyAAQAAAEAAQB3yEczW8w8N5/YC5cfOrhGAxRAmCl1uN0BzTeiCAXuCQNjY2LEhx1Vits2GeSVqtn7m774ta2+3WnIHhZByJjH4a5ad2KYqZOVAne/jhKByD3XApgT1ocACdb6md3Whbf7n5miUFsHVVY8wqVIh1HpDR3tnhtSoTYMVJFgA7ILx4Hr8XQC2t7q6uD3UY0622kmqR3jQ0kmOvek6qWr0o9sB+aPbisjUh4RKdMCw+4JWvgF9Vbnk9HlH7lHuMxJyP73D5FNRmmjLMFNQ4Dk23gS8h4C0x0x0AeK6USZZG/EXiWTFy8Jvwb/sdgzBngiw+GHa+SgnixtVl0DMDBnN//HAcYXWHGVmCwaQEFYPoARWH1PVfZQ8/pCdHb1ju8O/5jTETtBuj3b3J1aP2QxL07zmsi//RWXXmLnd0d8aIQhKdeOOibcvSLKCZcvOrv+SSSaZPhSQZ2uYYCENu93gLm5q57j3iuzxwUagKXAHRIcBU0LR3kw52V89YG+To2TFlq77KYZS98otYMqEYy+1dyL3mWLK7Y3X61Op9pU1hdaVOLMgNhvYmoV71oHUIF368lOHR7LUNu2vufyGClFcQpZAQJW5+VGQ8iJfBfQNA8LDhlcCO30LkGriG4lmHkHj6gxjFhRwsZA3h/HvWAZDUYX3+syF+m8KQ1ZWEwoKhGbvFu486whDGAbHSQ2fHmZbAN3kPodkl/DMrqEFiXePpjzRC2aYRpKFfWK/tVQYvs0eGZOd/U0epXgMJp7NOyhHzQ="); TCHAR szCipher[]=_T("GV5v/edRWPFxuK0vG8UP0/vZ2m8U62xrvJLHLnuMuxbs6RumLqspT2dnU38HXjWSRaAH/EWoUWwkdMyUq3/fAsmO+vef6Xf0yUcg50Vy2wFkZdWpw3+htJ3eJaOo8nV1aXyRghR38C7/fRoDfmReIHH/cB+Udx7AgEY4LMCZiWM="); HCRYPTPROV hProv=NULL; HCRYPTKEY hPrivateKey; DWORD dwPrivateKeySize; BYTE *pbPrivateKey; DWORD dwCipherSize; BYTE* pbCipher; DWORD dwFlags=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); CryptStringToBinary(szCipher,0,CRYPT_STRING_BASE64,NULL,&dwCipherSize,0,0); pbCipher = (BYTE*)malloc(dwCipherSize); CryptStringToBinary(szCipher,0,CRYPT_STRING_BASE64,pbCipher,&dwCipherSize,0,0); CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, dwFlags); CryptImportKey(hProv,pbPrivateKey,dwPrivateKeySize,0,CRYPT_EXPORTABLE,&hPrivateKey); CryptDecrypt(hPrivateKey, NULL, FALSE, 0, (BYTE *)pbCipher, &dwCipherSize); return 0; } (:sourcend:) Comme dit plus haut, OpenSSL est capable d'interpréter nativement les structures spécifiques de Microsoft grâce à un nouveau format de certificat le MS, n'oublions pas non plus d'inverser le flux chiffré par la commande -rev et voici le résultat:
|