总章
http://msdn.microsoft.com/en-us/library/aa382019(v=VS.85).aspx
产生和Java或C#代码一致的HMAC-SHA1的结果:
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
byte[] data = { 0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65 };
byte[] output = sha1.ComputeHash(data);或者
byte[] bt = {0x6D, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65};MessageDigest md;
try {
md = MessageDigest.getInstance("SHA1");
md.update(bt);
byte[] output = md.digest();
} catch (NoSuchAlgorithmException e) {
}C using Win32 API的是什么样子的呢?
HCRYPTPROV hProv = NULL;BOOL bAcq = CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
if (bAcq)
{
HCRYPTHASH hHash = NULL;
BOOL bHash = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash);
if (bHash)
{
BYTE bytes[] = { 0x6D,0x65,0x73,0x73,0x61,0x67,0x65 };
BOOL bCrypt = CryptHashData(hHash, bytes, 7, 0);
if (bCrypt)
{
BYTE pHashResult[1024] = {0};
DWORD dwLen = 1024;
CryptGetHashParam(hHash, HP_HASHVAL, pHashResult, &dwLen, 0);
for (int i = 0; i < dwLen; ++i)
{
printf("%d ", pHashResult[i]);
}
}
}
}111 155 154 243 205 110 139 138 115 194 205 206 211 127 233 245 146 38 226 125
【这个应该是结果】
只依赖于Windows的MD5
#include <atlcrypt.h>
CString Get_MD5 (const void* p, int nLength)
{
CCryptProv prov ;
LRESULT l = prov.Initialize() ;
if (l == 0x80090016L)
{
prov.Initialize (PROV_RSA_FULL, NULL, MS_DEF_PROV, CRYPT_NEWKEYSET) ;
}
CCryptMD5Hash hash ;
hash.Initialize(prov) ;
BYTE buf[32] ;
DWORD dw = 32 ;
l = hash.AddData ((const BYTE*)p, nLength) ;
if (SUCCEEDED(l))
{
l = hash.GetValue (buf, &dw) ;
if (SUCCEEDED(l) && (dw == 16))
{
CString s ;
for (int i=0 ; i < (int)dw ; i++)
{
CString ch ;
ch.Format(_T("%02x"), (int)buf[i]) ;
s += ch ;
}
return s ;
}
}
return _T("") ;
}
BASE64
依赖于Win32的BASE64。
CryptBinaryToString
注意CRYPT_STRING_NOCRLF参数(XP不管用)
AES
AES的Provider问题.
http://brooks.wang.blog.163.com/blog/static/24222621200901411284760/
AES/ECB(电子密码本 模式):
我用的是CRijndael 实现。Very NICE!(发包还是要自己补位的)
我现在搞这些加密/解密的还是发憷!
以下的Java代码可以和下面的C++代码进行互解。但是要我自己补位才行【或者Data的Size是16,24,32 // blockSize - The block size in bytes of this Rijndael (16, 24 or 32 bytes).】。
public static void main(String[] args) throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = "Hello World!!!!!".getBytes(); //Block size Both are 16
byte[] keyBytes = "2222222211111111".getBytes();
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding", "BC");
System.out.println(new String(input));
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);... ...
C++:
try
{
char szHex[33];
//One block testing
CRijndael oRijndael;
oRijndael.MakeKey("2222222211111111", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 16);
char szDataIn[] = "Hello World";
char szDataOut[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
oRijndael.EncryptBlock(szDataIn, szDataOut);
CharStr2HexStr((unsigned char*)szDataIn, szHex, 16);
cout << szHex << endl;
CharStr2HexStr((unsigned char*)szDataOut, szHex, 16);
cout << szHex << endl;
memset(szDataIn, 0, 16);
oRijndael.DecryptBlock(szDataOut, szDataIn);
CharStr2HexStr((unsigned char*)szDataIn, szHex, 16);
cout << szHex << endl;
}
catch(exception& roException)
{
cout << roException.what() << endl;}
以上两段代码是可以互解的。
下面的代码,可以和我公司的进行互解,我相信下面的代码更好一些:我自己做的简单补位【据说大多数的补位都是这么玩的,就是按照16字节的整数倍补,差几个自己,空区填几】
#ifndef ___AES_HPP__#define ___AES_HPP__
#pragma once
#include <AES/Rijndael.h>
typedef CRijndael AES;
#endif
/* Example
static __inline DWORD _ALIGN_16(DWORD dwSize)
{
return ((dwSize >> 4) + 1) << 4;
}
static DWORD _AES_128_ECB_Encrypt(LPCSTR lpAesKey, BYTE* pBufferIn, DWORD dwBufferInSize, BYTE* pBufferOut)
{
AES aes;
aes.MakeKey(lpAesKey, "", 16, 16);
DWORD dwBufferSize = _ALIGN_16(dwBufferInSize);
// TODO: Optimize using a stack array;
BYTE* pBuffer = new BYTE[dwBufferSize];
// Padding with the value ( of the count to padding ).
memset( pBuffer, (dwBufferSize - dwBufferInSize), dwBufferSize);
memcpy( pBuffer, pBufferIn, dwBufferInSize);
aes.Encrypt( (const char*)pBuffer, (char*)pBufferOut, dwBufferSize, ECB);
delete[] pBuffer;
return dwBufferSize;
}
*/累死个人!