我在Delphi XE2中有以下代码来加密和解密字符串。
有什么不对,我获得了不同的加密结果?我需要用Delphi和C ++这两种语言读写一些字符串,我不想在Delphi中使用DLL编写来用C ++编写它
function CryptString(Const Input: string; password : AnsiString; Encrypt: Boolean) : string;
const
BufferSize=1024*1024;
var
StreamSource : TStringStream;
StreamDest : TStringStream;
CRYPTPROV : HCRYPTPROV;
CRYPTHASH : HCRYPTHASH;
CRYPTKEY : HCRYPTKEY;
Buffer : LPBYTE;
BytesIn : DWORD;
Final : Boolean;
Encoder : TIdEncoderMIME;
Decoder : TIdDecoderMIME;
DestStream : TStringStream;
begin
CryptAcquireContext(CRYPTPROV, nil, MS_DEF_DH_SCHANNEL_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
try
//create a valid key based in the password
if not CryptCreateHash(CRYPTPROV, CALG_SHA1, 0, 0, CRYPTHASH) then RaiseLastOSError;
try
if not CryptHashData(CRYPTHASH, @Password[1], Length(Password), 0) then RaiseLastOSError;
if not CryptDeriveKey(CRYPTPROV, CALG_RC4, CRYPTHASH, 0, CRYPTKEY) then RaiseLastOSError;
finally
CryptDestroyHash(CRYPTHASH);
end;
StreamSource := TStringStream.Create(Input);
StreamSource.Position := 0;
StreamDest := TStringStream.Create;
try
GetMem(Buffer, BufferSize);
try
if not Encrypt then
begin
//decode the string using base64
Decoder := TIdDecoderMIME.Create(nil);
try
DestStream := TStringStream.Create;
try
StreamDest.Position:=0;
Decoder.DecodeBegin(DestStream);
Decoder.Decode(StreamSource);
Decoder.DecodeEnd;
StreamSource.Clear;
DestStream.Position:=0;
StreamSource.CopyFrom(DestStream,DestStream.Size);
StreamSource.Position:=0;
finally
FreeAndNil( DestStream);
end;
finally
FreeAndNil( Decoder);
end;
end;
repeat
BytesIn := StreamSource.Read(Buffer^, BufferSize);
Final := (StreamSource.Position >= StreamSource.Size);
if Encrypt then begin
if not CryptEncrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn, BytesIn) then
RaiseLastOSError;
end
else if not CryptDecrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn) then
RaiseLastOSError;
StreamDest.Write(Buffer^, BytesIn);
until Final;
//encode the string using base64
if Encrypt then
begin
Encoder := TIdEncoderMIME.Create(nil);
try
DestStream:=TStringStream.Create;
try
StreamDest.Position:=0;
Encoder.Encode(StreamDest,DestStream);
Result := DestStream.DataString;
finally
FreeAndNil( DestStream);
end;
finally
FreeAndNil(Encoder);
end;
end
else
Result:= StreamDest.DataString;
finally
FreeMem(Buffer, BufferSize);
end;
finally
FreeAndNil( StreamSource);
FreeAndNil( StreamDest);
end;
finally
CryptReleaseContext(CRYPTPROV, 0);
end;
end;
我在C ++中发现以下代码可以做同样的事情,但加密结果不同。
int main()
{
const char* passw = "teste";
const char* toencrypt = "sa";
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(toencrypt);
PBYTE pBuffer;
CryptAcquireContext(&hProv, NULL, NULL , PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptCreateHash(hProv, CALG_SHA1 , 0, 0, &hHash);
CryptHashData(hHash, (BYTE*)passw, strlen(passw), 0);
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey);
CryptDestroyHash(hHash);
//--------------------------------------------------------------------
pBuffer = (BYTE *)malloc(todwSize);
strcpy((char*)pBuffer, toencrypt);
CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, todwSize);
PBYTE pBreturn = pBuffer;
const char* message = (const char*)pBreturn;
printf("%s", message);
system("pause");
//--------------------------------------------------------------------
DWORD dwSize = (DWORD)strlen(message);
PBYTE depBuffer;
depBuffer = (BYTE *)malloc(1460);
strcpy((char*)depBuffer, message);
CryptDecrypt(hKey, 0, TRUE, 0, depBuffer, &dwSize);
CryptDestroyKey(hKey);
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
if (GetLastError() != 0)
{
printf("%d", GetLastError());
}
PBYTE depBreturn = depBuffer;
printf("%s", (const char*)depBreturn);
printf("\n%d", strlen(message));
return 0;
}
答案 0 :(得分:0)
这段代码显示如何加密字符串,解密字符串,加密字符串和解密字符串转换为base64,就像上面的Delphi代码一样。在Vc ++中 此代码的一部分基于CryptEncrypt does not encrypt whole text
#include "stdafx.h"
#include <atlenc.h>
#include <atlstr.h>
#include <locale.h>
static const unsigned char pr2six[256] =
{
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
};
int Base64decode_len(const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
return nbytesdecoded + 1;
}
int Base64decode(char *bufplain, const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
register unsigned char *bufout;
register int nprbytes;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63);
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
bufout = (unsigned char *)bufplain;
bufin = (const unsigned char *)bufcoded;
while (nprbytes > 4) {
*(bufout++) =
(unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) =
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) =
(unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
bufin += 4;
nprbytes -= 4;
}
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
if (nprbytes > 1) {
*(bufout++) =
(unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
*(bufout++) =
(unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
if (nprbytes > 3) {
*(bufout++) =
(unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
}
*(bufout++) = '\0';
nbytesdecoded -= (4 - nprbytes) & 3;
return nbytesdecoded;
}
static const char basis_64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int Base64encode_len(int len)
{
return ((len + 2) / 3 * 4) + 1;
}
int Base64encode(char *encoded, const char *string, int len)
{
int i;
char *p;
p = encoded;
for (i = 0; i < len - 2; i += 3) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) |
((int)(string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
}
else {
*p++ = basis_64[((string[i] & 0x3) << 4) |
((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
*p++ = '=';
}
*p++ = '\0';
return p - encoded;
}
bool encryptStr(const char *pSourceTxt,const char* pKey, int length, char * pEncryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pSourceTxt), needSize;
PBYTE pBuffer;
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0))
{
memcpy(pBuffer = (BYTE *)_alloca(needSize), pSourceTxt, todwSize);
if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pEncryptTxt, txtBuf, todwSize + 1);
}
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool encryptStrBase64(const char *pSourceTxt, const char* pKey, int length, char * pEncryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pSourceTxt), needSize;
PBYTE pBuffer;
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
if (CryptEncrypt(hKey, 0, TRUE, 0, NULL, &(needSize = todwSize), 0))
{
memcpy(pBuffer = (BYTE *)_alloca(needSize), pSourceTxt, todwSize);
if (CryptEncrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize, needSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
char *txtEncode64 = (char *)_alloca(strlen(pEncryptTxt));
Base64encode(txtEncode64, txtBuf, todwSize);
memcpy(pEncryptTxt, txtEncode64, todwSize +100);
}
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool decryptStr(const char *pEncryptTxt, const char* pKey, int length, char * pDecryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
DWORD todwSize = (DWORD)strlen(pEncryptTxt);
PBYTE pBuffer = (BYTE *)_alloca(todwSize);
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
memcpy(pBuffer, pEncryptTxt, todwSize);
if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pDecryptTxt, txtBuf, todwSize + 1);
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
bool decryptStrBase64(const char *pEncryptTxt, const char* pKey, int length, char * pDecryptTxt)
{
HCRYPTPROV hProv;
HCRYPTHASH hHash;
HCRYPTKEY hKey;
char *sourceTxt = (char *)_alloca(2048);
Base64decode(sourceTxt, pEncryptTxt);
DWORD todwSize = (DWORD)strlen(sourceTxt);
PBYTE pBuffer = (BYTE *)_alloca(todwSize);
char *txtBuf = (char *)_alloca(todwSize + 1);
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
if (CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
{
if (CryptHashData(hHash, (BYTE*)pKey, (DWORD)strlen(pKey), 0) &&
CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hKey))
{
memcpy(pBuffer, sourceTxt, todwSize);
if (CryptDecrypt(hKey, 0, TRUE, 0, pBuffer, &todwSize))
{
txtBuf[todwSize] = NULL;
memcpy(txtBuf, pBuffer, todwSize);
memcpy(pDecryptTxt, txtBuf, todwSize + 1);
}
CryptDestroyKey(hKey);
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return true;
}
int main()
{
char* encryptWord = "test word";
char *encryptKey = "cryptkey";
int encryptLen = strlen(encryptWord);
char * txtEncrypt = (char *)_alloca(encryptLen+1);
//simple Encrypt TXT
encryptStr(encryptWord, encryptKey, encryptLen,txtEncrypt);
printf("Simple Encrypt %s \n", txtEncrypt);
//Decrypt string
char* decryptTxt = (char *)_alloca(encryptLen + 1);
decryptStr(txtEncrypt, encryptKey, encryptLen, decryptTxt);
printf("Txt decrypted %s \n", decryptTxt);
//Encrypt and Convert to Base64 like delphi Routine
char* base64TxtEncrypt = (char*)_alloca(encryptLen + 100);//need aloc more size due base64 routine
encryptStrBase64(encryptWord, encryptKey, encryptLen, base64TxtEncrypt);
printf("Base64 txt encrypted %s \n", base64TxtEncrypt);
//decrypt and Convert to original String like delphi Routine
char* base64TxtDecrypt = (char*)_alloca(encryptLen + 100);
decryptStrBase64( base64TxtEncrypt, encryptKey, strlen(base64TxtEncrypt) , base64TxtDecrypt);
printf("Base64 txt Decrypted %s \n", base64TxtDecrypt);
system("pause");
return 0;
}
最后将此代码转换为c#和任务结束
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace CryptCsharpNativo
{
class Program
{
public const uint PROV_RSA_FULL = 1;
public const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
public const uint CRYPT_NEWKEYSET = 0x00000008;
public enum ALG_ID
{
CALG_MD5 = 0x00008003,
CALG_RC4 = 0x00006801,
CALG_SHA1 = 0x00008004
}
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCreateHash(IntPtr hProv, ALG_ID Algid, IntPtr hKey, uint dwFlags, out IntPtr phHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, int dwDataLen, uint dwFlags);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDeriveKey(IntPtr hProv, ALG_ID Algid, IntPtr hBaseData, uint dwFlags, ref IntPtr phKey);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyHash(IntPtr hHash);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, [MarshalAs(UnmanagedType.Bool)]bool Final, uint dwFlags, byte[] pbData, ref int pdwDataLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, [MarshalAs(UnmanagedType.Bool)]bool Final, uint dwFlags, byte[] pbData, ref int pdwDataLen);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDestroyKey(IntPtr hKey);
[DllImport("advapi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);
const uint NTE_BAD_KEYSET = 0x80090016;
public static string decryptStr(string pSourceTxt, string pKey)
{
IntPtr hCryptProv;
IntPtr hKey = IntPtr.Zero;
IntPtr hHash;
int dwCount = 0;
byte[] key = Encoding.ASCII.GetBytes(pKey);
int datalen = pSourceTxt.Length;
// Get a handle to the default provider.
if (!CryptAcquireContext(out hCryptProv, null, null, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return "";
}
// Decrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash(hCryptProv, ALG_ID.CALG_SHA1, IntPtr.Zero, 0, out hHash))
return "";
// Hash in the password data.
if (!CryptHashData(hHash, key, key.Length, 0))
return "";
// Derive a session key from the hash object.
if (!CryptDeriveKey(hCryptProv, ALG_ID.CALG_RC4, hHash, 0, ref hKey))
return "";
// Destroy the hash object.
if (!(CryptDestroyHash(hHash)))
return "";
hHash = IntPtr.Zero;
byte[] originalCrypt = Convert.FromBase64String(pSourceTxt);
if (!CryptDecrypt(hKey, IntPtr.Zero, true, 0, originalCrypt, ref datalen))
return "";
datalen = dwCount;
// Destroy session key.
if (hKey != IntPtr.Zero)
{
if (!(CryptDestroyKey(hKey)))
return "";
}
// Release provider handle.
if (hCryptProv != IntPtr.Zero)
{
if (!(CryptReleaseContext(hCryptProv, 0)))
return "";
}
return Encoding.ASCII.GetString(originalCrypt);
} // end Decryptfile
public static string encryptStr(string pSourceTxt, string pKey)
{
IntPtr hCryptProv;
IntPtr hKey = IntPtr.Zero;
IntPtr hHash;
int dwCount = 0;
byte[] sourceTxt = Encoding.ASCII.GetBytes(pSourceTxt);
byte[] key = Encoding.ASCII.GetBytes(pKey);
int datalen = pSourceTxt.Length;
// Get a handle to the default provider.
if (!CryptAcquireContext(out hCryptProv, null, null, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return "";
}
// Decrypt the file with a session key derived from a password.
// Create a hash object.
if (!CryptCreateHash(hCryptProv, ALG_ID.CALG_SHA1, IntPtr.Zero, 0, out hHash))
return "";
// Hash in the password data.
if (!CryptHashData(hHash, key, key.Length, 0))
return "";
// Derive a session key from the hash object.
if (!CryptDeriveKey(hCryptProv, ALG_ID.CALG_RC4 , hHash, 0, ref hKey))
return "";
// Destroy the hash object.
if (!(CryptDestroyHash(hHash)))
return "";
hHash = IntPtr.Zero;
if (!CryptEncrypt(hKey, IntPtr.Zero, true, 0, null, ref datalen))
return "";
if (!CryptEncrypt(hKey, IntPtr.Zero, true, 0, sourceTxt, ref datalen))
return "";
string base64 = Convert.ToBase64String(sourceTxt);
datalen = dwCount;
// Destroy session key.
if (hKey != IntPtr.Zero)
{
if (!(CryptDestroyKey(hKey)))
return "";
}
// Release provider handle.
if (hCryptProv != IntPtr.Zero)
{
if (!(CryptReleaseContext(hCryptProv, 0)))
return "";
}
return base64;
} // end encryptfile
static void Main(string[] args)
{
string encryptTxt = "Teste Crypt";
string key = "teste123";
string encryptStr = Program.encryptStr(encryptTxt, key);
string decryptStr = Program.decryptStr(encryptStr, key);
Console.Write("Encrypt String with Base64 = {0} \n" , encryptStr);
Console.Write("Decrypted String with base64 = {0}", decryptStr);
Console.ReadLine();
}
}
}