MS Crypto API and Sun's JCE producing different MD5 MAC Results.

From: Adrian (aprz43_at_yahoo.com.au)
Date: 06/01/04

  • Next message: Rhett Gong [MSFT]: "Re: Secure dynamic updates on Windows 2003 DNS Server"
    Date: 31 May 2004 23:44:42 -0700
    
    

    Hi Guys,

    I am writing a c++ service using the CryptoAPI which needs to produce
    an RSA MD5 Mac code for a message.
    This Mac code then gets validated bt a 3rd party application written
    in Java. This is using Sun's JCE version 1.22 for its MAC function.
    The problem is that the MS & Java functions seems to produce 2
    different MAC values using the same key and the same input data.

    My code is as follows:

    This is the C++ Code:

    HRESULT CSecureDataMgr::HashData(CByteBuffer&
    bufBytesData1,CByteBuffer& bufBytesData2,CByteBuffer& bufHashBuffer,
    CComBSTR& bstrErrMsg)
    {
            HRESULT hr = S_OK;
            BOOL bHashed = FALSE;

        CRYPT_HASH_MESSAGE_PARA stHashParms;
            BYTE * paHashBuffer = NULL;
            DWORD dwHashBufferSize = DEFAULT_HASH_BUFFER_SIZE;
            const BYTE* rgpbToBeHashed[3];
            DWORD rgcbToBeHashed[3];

            DebugTrace(_T("CSecureDataMgr::HashData() has been called. Data
    buffer size is (%d) bytes. Context buffer size is (%d)
    bytes."),bufBytesData1.m_dwSize,bufBytesData2.m_dwSize);

            // Initialize hashing parameters.
            ZeroMemory(&stHashParms,sizeof(stHashParms));
            ZeroMemory(&rgpbToBeHashed,sizeof(rgpbToBeHashed));
            ZeroMemory(&rgcbToBeHashed,sizeof(rgcbToBeHashed));
     
            // We want hash the contents of the BSTR
            stHashParms.cbSize = sizeof(stHashParms);
        
            // Set the encoding type.
            stHashParms.dwMsgEncodingType = X509_ASN_ENCODING |
    PKCS_7_ASN_ENCODING;

            // Set the cryptographic provider name to null (this will default to
    RSA)
            stHashParms.hCryptProv = NULL;

            // set auxillary info to null (we dont use it)
            stHashParms.pvHashAuxInfo = NULL;

            // Set the algorithm used to perform the hashing. Note we opt for RSA
    MD5 here.
            stHashParms.HashAlgorithm.pszObjId = szOID_RSA_MD5;
            stHashParms.HashAlgorithm.Parameters.cbData = 0;

            while (SUCCEEDED(hr) && (bufHashBuffer.m_pBytes == NULL))
            {
                    // initialize hashing buffer structure
                    rgpbToBeHashed[0] = g_abCSecureDataMgrKey;
                    rgcbToBeHashed[0] = sizeof(g_abCSecureDataMgrKey);
                    rgpbToBeHashed[1] = bufBytesData1.m_pBytes;
                    rgcbToBeHashed[1] = bufBytesData1.m_dwSize;
                    rgpbToBeHashed[2] = bufBytesData2.m_pBytes;
                    rgcbToBeHashed[2] = bufBytesData2.m_dwSize;

                    // Allocate and intialize a buffer to receive the hashed value.
                    bufHashBuffer.Alloc(dwHashBufferSize);
     
                    // Attempt to hash the message.
                    bHashed = CryptHashMessage(&stHashParms,
                                                   TRUE,
                                                                       3,
                                                                       rgpbToBeHashed,
                                                                       rgcbToBeHashed,
                                                                       NULL,
                                                                       NULL,
                                                                       bufHashBuffer.m_pBytes,
                                                                       &dwHashBufferSize);

    ******************************************************************************

    This is the JAVA Code:

            public String test(String message, byte[] keyBytes) throws Exception
            {
                    Provider sunJce = new com.sun.crypto.provider.SunJCE();
                    Security.insertProviderAt(sunJce,0);

                    //create key object
                    SecretKey key = new SecretKeySpec(keyBytes, "HmacMD5");
                    
                    // Create a MAC object using HMAC-MD5 and initialize with key
                    Mac mac = Mac.getInstance("HmacMD5");
                    mac.init(key);
                                    
                    // Encode the string into bytes using utf-8 and digest it
                    byte[] utf8 = message.getBytes();
                    byte[] digest = mac.doFinal(utf8);

                    // If desired, convert the digest into a string
                    String digestB64 = new sun.misc.BASE64Encoder().encode(digest);
            
                    return digestB64;
            }
            
    *****************************************************************************

    After I convert the C++ result to a string I get a completely
    different value to the Java value.

    What am I doing wrong?

    Thanks,

    Adrian


  • Next message: Rhett Gong [MSFT]: "Re: Secure dynamic updates on Windows 2003 DNS Server"
  • Quantcast