心寄笔端 附庸风雅

甘草的技术博客

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

总章

http://msdn.microsoft.com/en-us/library/aa382019(v=VS.85).aspx 

 

 

产生和Java或C#代码一致的HMAC-SHA1的结果:

SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();            
byte[] data = { 0x6D0x650x730x730x610x670x65 };
byte[] output = sha1.ComputeHash(data);

或者

        byte[] bt = {0x6D0x650x730x730x610x670x65};
        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, 00&hHash);
        
if (bHash)
        {
            BYTE bytes[] 
= { 0x6D,0x65,0x73,0x73,0x61,0x67,0x65 };
            BOOL bCrypt 
= CryptHashData(hHash, bytes, 70);
            
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"1616);
        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, 016);
        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;
}
*/

累死个人!

 

 

 

 

 

 

 

 

 

posted on 2010-11-29 11:43  甘草  阅读(1030)  评论(0编辑  收藏  举报
Baidu
Google
心寄笔端
TEST
以后我会加上Power By的,先别介意