2013-10-17 21 views
9

İstemci tarafındaki (JavaScript) dizgiyi şifrelemem ve sunucu tarafındaki (Java) şifresini çözmem gerekiyor, böylece CryptoJS'yi buldum ve aynı param/mi Java Kodu ama çıktı her zaman farklıdır, herhangi bir fikrin var mı, yoksa ne olacak?Hem CryptoJS hem de Java Code farklı çıktı şifrelemesi

Ben kullanım olduğum CBC NoPadding ile

CryptoJS

http://jsfiddle.net/Soldier/gCHAG/

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"> 
</script> 
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/pad-nopadding-min.js"></script> 
<script> 

    function padString(source) { 
     var paddingChar = ' '; 
     var size = 16; 
     var x = source.length % size; 
     var padLength = size - x; 

     for (var i = 0; i < padLength; i++) source += paddingChar; 

     return source; 
    } 

    var key = CryptoJS.enc.Hex.parse('abcdef'); 
    var iv = CryptoJS.enc.Hex.parse('fedcba'); 
    var message = "soldier"; 
    var padMsg = padString(message); 

    var encrypted = CryptoJS.AES.encrypt(padMsg, key, { iv: iv, padding: CryptoJS.pad.NoPadding, mode: CryptoJS.mode.CBC}); 

    console.log("Encrypted: "+encrypted); 
    console.log("Encrypted text: "+encrypted.ciphertext); 

</script> 

Java Kod

import java.security.Key; 
import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import sun.misc.*; 

public class AesCipher { 

    private static final String algorithm = "AES/CBC/NoPadding"; 

    private static final byte[] keyValue = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 
    private static final byte[] ivValue = new byte[] { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8', '7', '6', '5', '4', '3', '2', '1', '0' }; 

    private static final IvParameterSpec ivspec = new IvParameterSpec(ivValue); 
    private static final SecretKeySpec keyspec = new SecretKeySpec(keyValue, "AES"); 

    final protected static char[] hexArray = "ABCDEF".toCharArray(); 

    public static String encrypt(String Data) throws Exception { 
     Cipher c = Cipher.getInstance(algorithm); 
     c.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); 
     byte[] encVal = c.doFinal(Data.getBytes()); 
     String encryptedValue = new BASE64Encoder().encode(encVal); 
     return encryptedValue; 
    } 

    public static String decrypt(String encryptedData) throws Exception { 
     Cipher c = Cipher.getInstance(algorithm); 
     c.init(Cipher.DECRYPT_MODE, keyspec, ivspec); 
     byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
     byte[] decValue = c.doFinal(decordedValue); 
     String decryptedValue = new String(decValue); 
     return decryptedValue; 
    } 

    public static String bytesToHex(byte[] bytes) { 
     char[] hexChars = new char[bytes.length * 2]; 
     int v; 
     for (int j = 0; j < bytes.length; j++) { 
      v = bytes[j] & 0xFF; 
      hexChars[j * 2] = hexArray[v >>> 4]; 
      hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
     } 
     return new String(hexChars); 
    } 

    private static String padString(String source) { 
     char paddingChar = ' '; 
     int size = 16; 
     int x = source.length() % size; 
     int padLength = size - x; 

     for (int i = 0; i < padLength; i++) 
     { 
      source += paddingChar; 
     } 
     return source; 
     } 

    public static void main(String[] args) throws Exception { 

     String password = "soldier"; 
     String passwordEnc = AesCipher.encrypt(padString(password)); 
     String passwordDec = AesCipher.decrypt(passwordEnc); 

     System.out.println("Plain Text : " + password); 
     System.out.println("Encrypted Text : " + passwordEnc); 
     System.out.println("Decrypted Text : " + passwordDec); 
    } 

} 

Orijinal dize: CryptoJS dan

soldier 

Çıktı: Java Code dan

Encrypted: VNzZNKJTqfRbM7zO/M4cDQ== 
Encrypted Hex: 54dcd934a253a9f45b33bccefcce1c0d 

Çıktı: şifreli

Encrypted: j6dSmg2lfjY2RpN91GNgNw== 
Encrypted Hex: 6a3664536d67326c666a593252704e3931474e674e773d3d 

base64 dize aynı uzunlukta ancak altıgen vardır. Java Kodunda CryptoJS'in çıktı sonucunu koyarsam, şifre çözme yanlıştır.

Selamlar,

cevap

7

Burada sorun, anahtar girdinizin tutarsız olması.

  • CryptoJS.enc.Hex.parse('abcdef')

    iki basamaklı heks değerleri olarak ifade bayt serisi olarak giriş okur: 01, 23, 45 vb

  • Java dizi bayt karakter kodlama değerleri kullanılarak değerleri belirler Karakterlerin. Yani, (hex) bayt dizisidir: 30 (ondalık 48, '0' için ASCII kodu), sonra 31 (ondalık 49, '1' için ASCII code) yapabilir vb

JavaScript uygun http://jsfiddle.net/gCHAG/1/ (bu aynı j6dSm... çıktıyı üretir)

Ancak, muhtemelen her hane kendi byte olmak istiyorum: bireysel karakter değerleri okumak ve bayt değerleri olarak bunları kullanacağız CryptoJS.enc.Latin1.parse kullanarak Java uygulamasına. Bunu yapmak için her iki uygulamayı da değiştirmeniz gerekir.

Java:

// use hex literals, not characters 
byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; 
// array values: 0x00, 0x01, 0x02, etc 

JavaScript:

// remember each bytes is two digits wide 
CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f') 
// array values: 0x00, 0x01, 0x02, etc 
+0

İyi çalışıyor, çok teşekkürler :) – SoldierCorp

1

karakter '0' 0. CryptoJS anahtar büyük olasılıkla farklı onlara farklı nesne türlerini başlatmasını çünkü Java anahtarının daha onaltılık değeri olarak aynı değildir. Oluşturduktan sonra her iki dilde de/IV tuşlarını yazdırın ve karşılaştırın.

DÜZENLEME: Bu, özel kripto kitaplıkları ile ilgili sorular burada konu dışı olmadığından, muhtemelen StackOverflow'a taşınacaktır.

+0

Yup üzerinde yerini java

var key = CryptoJS.MD5("Secret Passphrase"); 

üzerine değiştirin (IV için aynı olabilir) . Şimdi düzenleniyor. – pg1989

0

Çok yararlı bir örnek SoldierCorp, teşekkür ederim!

  • Yöntem padString UTF8 desteklemek ve bunun yerine bu yöntemi sabitleme

    üzerine yerine javascript standart dolgu

silip kullanmanızı sağlar ait değildir:

Birkaç şey olarak örnek iyileştirmek için

padding: CryptoJS.pad.Pkcs7 

java yerine

yerine
algorithm = "AES/CBC/PKCS5Padding" 
  • herhangi bir dize ifadeden anahtarı oluşturun javascript

üzgün,

byte[] keyValue = org.apache.commons.codec.digest.DigestUtils.md5("Secret Passphrase"); 
+0

Anahtar türevlemede MD5 kullanmak iyi bir fikir değil bence. PBKDF2'yi kullanmak daha iyidir. İyi ki, CryptoJS ve Java'nın her ikisi de PBKDF2'yi yerel olarak destekliyor. –

İlgili konular