首页 文章

使用C和WinCrypt加密(RSA算法)库和使用C#解密

提问于
浏览
2

我希望加密C和WinCrypt(RSA算法)库和C#解密

I do Encryption and decryption with C++ successfully, but when i want decryption, encryption text with C# Exception throw : "Error occurred while decoding OAEP padding."

以下代码为C:

void main()
{
Acqired();
Generate2048BitKeys();
ExportPrivateKey(L"privateKey.txt");
ExportPublicKey(L"publicKey.txt");

// Encrypt
ImportKey(L"publicKey.txt");
EncryptDataWriteToFile(L"New Text For Encryption...", L"encryptedData.txt");
DestroyKeys();

// Decrypt
Acqired();
ImportKey(L"privateKey.txt");
LPBYTE lpDecryptedData = NULL;
DWORD dwDataLen = 0;
DecryptDataFromFile(&lpDecryptedData, L"encryptedData.txt", &dwDataLen);
WriteBytesFile(L"decryptedData.txt", lpDecryptedData, dwDataLen);
}
void DestroyKeys()
 {
if (hKey != NULL)
{
    CryptDestroyKey(hKey);
    hKey = NULL;
}

if (hProvider != NULL)
{
    CryptReleaseContext(hProvider, 0);
    hProvider = NULL;
   }
 }
 void Acqired()
 {
  BOOL res = CryptAcquireContext(&hProvider, NULL, MS_ENHANCED_PROV, 
   PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
if (!res)
{
    std::printf("Error Acquiring Key Context\n");
    return;
}
std::printf("Key Context Acquired\n");
 }
 void Generate2048BitKeys()
 {
const DWORD RSA2048BIT_KEY = 0x8000000;
DWORD dwParams;
dwParams = RSA2048BIT_KEY | CRYPT_EXPORTABLE | CRYPT_NO_SALT;   //set the 
 key length to 2048 bits, allow the keys to be exported, no salt
bool res = CryptGenKey(hProvider, AT_KEYEXCHANGE, dwParams, &hKey);
if (!res)
{
    printf("SERVER: Unable to generate exchange keys\n");
    return;
}
printf("SERVER: Exchange keys generated\n");
}
 void ExportPrivateKey(LPTSTR lpFileName)
{
if (hKey == NULL)
{
    printf("Error in function 'ExportPrivateKey', hKey is NULL\n");
    return;
}

DWORD dwDataLen = 0;
bool exportResult = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, NULL, &dwDataLen);
LPBYTE lpKeyBlob = (LPBYTE)malloc(dwDataLen);
exportResult = CryptExportKey(hKey, NULL, PRIVATEKEYBLOB, 0, lpKeyBlob, &dwDataLen);
WriteBytesFile(lpFileName, lpKeyBlob, dwDataLen);
free(lpKeyBlob);
 }
void ExportPublicKey(LPTSTR lpFileName)
 {
if (hKey == NULL)
{
    printf("Error in function 'ExportPublicKey', hKey is NULL\n");
    return;
}

DWORD dwDataLen = 0;
bool exportResult = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwDataLen);
LPBYTE lpKeyBlob = (LPBYTE)malloc(dwDataLen);
exportResult = CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, lpKeyBlob, &dwDataLen);
WriteBytesFile(lpFileName, lpKeyBlob, dwDataLen);
free(lpKeyBlob);
}
void ImportKey(LPTSTR lpFileName)
{
if (hProvider == NULL)
{
    printf("Error in function ImportKey, hProvider is NULL\n");
    return;
}

if (hKey != NULL)
    CryptDestroyKey(hKey);

LPBYTE lpKeyContent = NULL;
DWORD dwDataLen = 0;
ReadBytesFile(lpFileName, &lpKeyContent, &dwDataLen);
bool importResult = CryptImportKey(hProvider, lpKeyContent, dwDataLen, 0, CRYPT_OAEP, &hKey);
if (!importResult)
{
    printf("Error in function ImportKey, CryptImportKey is failed\n");
    return;
}

delete[] lpKeyContent;
}
void EncryptDataWriteToFile(LPTSTR lpSimpleDataToEncrypt, LPTSTR lpFileName)
{
DWORD SimpleDataToEncryptLength = _tcslen(lpSimpleDataToEncrypt) * sizeof(TCHAR);
DWORD BufferLength = SimpleDataToEncryptLength * 10;
BYTE *EncryptedBuffer = new BYTE[BufferLength];

SecureZeroMemory(EncryptedBuffer, BufferLength);
CopyMemory(EncryptedBuffer, lpSimpleDataToEncrypt, 
 SimpleDataToEncryptLength);

bool cryptResult = CryptEncrypt(hKey, NULL, TRUE, CRYPT_OAEP, EncryptedBuffer, &SimpleDataToEncryptLength, BufferLength);
if (!cryptResult)
{
    printf("Error in function EncryptDataWriteToFile, CryptEncrypt is failed\n");
    return;
}

WriteBytesFile(lpFileName, EncryptedBuffer, SimpleDataToEncryptLength);
delete[] EncryptedBuffer;

printf("Encrypt Data Successfully\n");
}
 void DecryptDataFromFile(LPBYTE *lpDecryptedData, LPTSTR lpFileName, DWORD *dwDecryptedLen)
{
if (hKey == NULL)
{
    printf("Error in function 'DecryptDataFromFile', hKey is NULL.\n");
    return;
}

LPBYTE lpEncryptedData = NULL;
DWORD dwDataLen = 0;
ReadBytesFile(lpFileName, &lpEncryptedData, &dwDataLen);

bool decryptResult = CryptDecrypt(hKey, NULL, TRUE, CRYPT_OAEP, lpEncryptedData, &dwDataLen);
if (!decryptResult)
{
    printf("Error in function 'DecryptDataFromFile', CryptDecrypt cann't be decrypted data.\n");
    return;
}
printf("decrypted Successfully ... \n");
*dwDecryptedLen = dwDataLen;
*lpDecryptedData = new BYTE[dwDataLen + 1];
SecureZeroMemory(*lpDecryptedData, dwDataLen + 1);
CopyMemory(*lpDecryptedData, lpEncryptedData, dwDataLen);

delete[]lpEncryptedData;
}
 void WriteBytesFile(LPTSTR lpFileName, BYTE* content, DWORD dwDataLen)
 {
HANDLE hFile = CreateFile(lpFileName, GENERIC_READ | GENERIC_WRITE, 0x7, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwBytesWritten = 0;
bool result = WriteFile(hFile, content, dwDataLen, &dwBytesWritten, NULL);
CloseHandle(hFile);
}
void ReadBytesFile(LPTSTR lpFileName, BYTE **content, DWORD *dwDataLen)
{
HANDLE hFile = CreateFile(lpFileName, GENERIC_READ, 0x7, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwFileLength = 0;
DWORD dwBytesToRead = GetFileSize(hFile, NULL);
DWORD dwBytesRead = 0;

*content = new BYTE[dwBytesToRead + 1];
SecureZeroMemory(*content, dwBytesToRead + 1);

ReadFile(hFile, *content, dwBytesToRead, &dwBytesRead, NULL);

*dwDataLen = dwBytesRead;

CloseHandle(hFile);
}

和C#代码是:

const int PROVIDER_RSA_FULL = 1;
    const string SERVICE_PROVIDER = "Microsoft Enhanced Cryptographic Provider v1.0"; //128 bit encryption
    static void Main(string[] args)
    {
        //var publicKey = File.ReadAllBytes("D:\\RSA\\pubkey.afp");
        var privateKey = File.ReadAllBytes("D:\\RSA\\privateKey.txt");
        var Data = File.ReadAllBytes("D:\\RSA\\encryptedData.txt");



        RSACryptoServiceProvider rsa;


        CspParameters cspParams;
        cspParams = new CspParameters(PROVIDER_RSA_FULL);

        cspParams.Flags =  CspProviderFlags.UseExistingKey | CspProviderFlags.UseMachineKeyStore;
        cspParams.ProviderName = SERVICE_PROVIDER;

        using (rsa = new RSACryptoServiceProvider(2048,cspParams))
        {
        rsa.ImportCspBlob(privateKey);
        // ----------------------------------------------------------------------
        byte[] result = rsa.Decrypt(Data, true);
        Console.WriteLine(Convert.ToString(result));
        }
    }

谁能帮我?

1 回答

  • 2

    这个问题的最佳方法是使用托管C

    创建lib C,在托管C中使用lib,然后就可以在C#中使用托管文件

相关问题