2016-08-23 25 views
0

這是java代碼。我試圖在JavaScript中複製相同的功能。將自定義消息認證代碼從Java轉換爲JavaScript

public String populateHMAC(String app_id, String mobile, String token, 
          String deviceId) { 

    String hmac = null; 
    try { 
     CryptLib cryptLib = new CryptLib(); 
     String message = app_id + "|" + mobile + "|" + deviceId; 
     byte[] tokenBytes = Base64.decode(token, 2);//cryptLib.hexStringToByteArray(token); 

     String temp=Base64.encodeToString(cryptLib.SHA256(message),2); 

     byte[] tempArr=Base64.decode(temp,2); 

     byte[] hmacBytes = cryptLib.encrypt(
       cryptLib.SHA256(message), 
       tokenBytes); 
     hmac = Base64.encodeToString(hmacBytes, Base64.DEFAULT); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return hmac; 
} 

這些是功能內部CryptLib

public byte[] SHA256(String paramString) throws Exception { 
    MessageDigest md = MessageDigest.getInstance("SHA-256"); 
    md.update(paramString.getBytes("UTF-8")); 
    byte[] digest = md.digest(); 
    return digest; 
} 

和加密函數

public byte[] encrypt(byte[] data, byte[] key) throws Exception { 
    SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); 
    byte[] iv = new byte[16]; 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    Cipher acipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    byte[] arrayOfByte1; 
    acipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 
    arrayOfByte1 = acipher.doFinal(data); 
    return arrayOfByte1; 
} 

這是相同的功能的JavaScript代碼。我正在使用crypto-js庫。

var crypto = require('crypto-js'); 

populateHMAC(app_id, mobile, token, deviceId){ 

    var rawStr = token; 
    var wordArray = crypto.enc.Utf8.parse(rawStr); 
    var base64 = crypto.enc.Base64.stringify(wordArray); 

    var enctoken=btoa(token); 


    var message= app_id + "|" + mobile + "|" + deviceId; 

    var decodedString= atob(enctoken); 

    message=encodeURIComponent(message); 

    var hash= crypto.SHA256(message);//.toString(crypto.enc.Utf8); 

    console.log("params",decodedString,hash.toString(crypto.enc.Hex)); 


    var iv = crypto.enc.Hex.parse('0000000000000000'); 
    var encryptedString = crypto.AES.encrypt(hash, decodedString, { 
       iv:iv, 
       mode: crypto.mode.CBC, 
       padding: crypto.pad.Pkcs7 
      }); 

    var encodedString= encryptedString.ciphertext.toString(crypto.enc.Base64); 


    return encodedString; 
} 

這兩個輸出是不同的,我無法弄清楚爲什麼。

+0

你在這裏提出的代碼是**不是** HMAC。它與CBC-MAC有一些相似之處,但那也不是。不要稱之爲HMAC。我寧願扔掉這些代碼並實施適當的HMAC。 Java和CryptoJS都支持實際的HMAC。 –

+0

是的,它不是hmac。但這是我必須複製的功能。它已經成了石頭,所以我不能丟棄它。 –

回答

0

的問題:

  • 我沒有看到的encodeURIComponent等效在Java代碼中使用。您可以刪除該行。

  • decodedString是CryptoJS將其視爲密碼的「二進制」字符串。你真的想令牌轉換爲CryptoJS理解的二進制表示:

    var decodedString = crypto.enc.Base64.parse(token); 
    

    在你的代碼的開頭刪除其他的編碼和解碼步驟。

  • '0000000000000000'如果它應該是Hex編碼的IV,則太短。它必須是獲得16個字節(32個hexits)的兩倍。