2016-08-23 7 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; 
} 

これらは、これは、同じ機能のためにJavaScriptコードである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; 
} 

内部関数です。私は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; 
} 

2つの出力が異なり、原因を特定できません。

+0

ここに示したコードは、** not ** HMACです。それはCBC-MACといくつかの類似点を持っていますが、そうではありません。それをHMACと呼んではいけません。むしろこのコードを捨て、適切なHMACを実装したいと思います。 JavaとCryptoJSの両方が実際のHMACをネイティブサポートしています。 –

+0

はい、それはhmacではありません。しかし、それは私が複製しなければならない機能です。私はそれを捨てることはできませんので、すでに石で設定されています。 –

答えて

0

問題:

  • 私はencodeURIComponentの同等のJavaコードで使用されていることがわかりません。その行を削除することができます。

  • decodedStringは、CryptoJSがパスワードとして扱う「バイナリ」文字列です。

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

    はあなたのコードの先頭で、他の符号化と復号化のステップを削除します。あなたは、実際にCryptoJSが理解できるバイナリ表現にトークンを変換したいです。

  • '0000000000000000'は、16進数でエンコードされたIVであると思われる場合は短すぎます。 16バイト(32桁)を取得するには、2倍の時間が必要です。

関連する問題