2016-06-23 8 views
-1

Ich habe diesen Code in meiner Rails-Anwendung:Wie kann ich den Java-Ciper-Algorithmus und den Ruby-Verschlüsselungsalgorithmus synchronisieren?

require 'openssl' 
require 'digest/sha1' 
require 'base64' 

KEY="secret_key" 
data = "secret message" 

def encrypt_value(data) 
    cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") 
    cipher.encrypt 
    cipher.key = Digest::SHA256.digest(KEY) 
    encrypted = cipher.update(data)+cipher.final 
    return encrypted 
end 

def decrypt_value1(data) 
    cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") 
    cipher.decrypt 
    cipher.key = Digest::SHA256.digest(KEY) 
    decrypted = cipher.update(data)+cipher.final 
    data = Base64.decode64(decrypted) 
    return data 
end 

und Java-Code:

import java.security.AlgorithmParameters; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.SecretKeySpec; 
import javax.xml.bind.DatatypeConverter; 

public class EncryptionDecryption { 

    private static String salt; 
    private static int iterations = 65536 ; 
    private static int keySize = 256; 
    private static byte[] ivBytes; 

    // private static SecretKey secretKey; 
    private static final byte[] secretKey = "secret_key".getBytes(); 

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

     salt = getSalt(); 

     char[] message = "secret message".toCharArray(); 
     System.out.println("Message: " + String.valueOf(message)); 
     System.out.println("Encrypted: " + encrypt(message)); 
     System.out.println("Decrypted: " + decrypt(encrypt(message).toCharArray())); 
    } 

    public static String encrypt(char[] plaintext) throws Exception { 
     byte[] saltBytes = salt.getBytes(); 

     SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
     PBEKeySpec spec = new PBEKeySpec(plaintext, saltBytes, iterations, keySize); 
     //secretKey = skf.generateSecret(spec); 
     SecretKeySpec secretSpec = new SecretKeySpec(secretKey, "AES"); 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretSpec); 
     AlgorithmParameters params = cipher.getParameters(); 
     ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV(); 
     byte[] encryptedTextBytes = cipher.doFinal(String.valueOf(plaintext).getBytes("UTF-8")); 

     return DatatypeConverter.printBase64Binary(encryptedTextBytes); 
    } 

    public static String decrypt(char[] encryptedText) throws Exception { 

     System.out.println(encryptedText); 

     byte[] encryptedTextBytes = DatatypeConverter.parseBase64Binary(new String(encryptedText)); 
     SecretKeySpec secretSpec = new SecretKeySpec(secretKey, "AES"); 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, secretSpec, new IvParameterSpec(ivBytes)); 

     byte[] decryptedTextBytes = null; 

     try { 
      decryptedTextBytes = cipher.doFinal(encryptedTextBytes); 
     } catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      e.printStackTrace(); 
     } 

     return new String(decryptedTextBytes); 

    } 

    public static String getSalt() throws Exception { 

     SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
     byte[] salt = new byte[20]; 
     sr.nextBytes(salt); 
     return new String(salt); 
    } 
} 

Wie kann ich beide habe miteinander arbeiten, zum Beispiel, wenn ich ein verschlüsselten Daten senden Java App von Rails App sollte es in der Lage sein, es zu entschlüsseln und umgekehrt.

+1

und welche dieser beiden Versionen sollte die bleiben, die bleibt? – zapl

+0

Versionen wie in? – sahil

+0

Sie haben eine einfache Verschlüsselung in Ruby und vs PBKDF mit Salz in Java. Sie können beide Versionen in beiden Sprachen verwenden, müssen jedoch angeben, welche Version Sie verwenden möchten. – zapl

Antwort

0

Soweit Sie die gleichen Chiffrieralgorithmen und Nachrichten padding Zeichen verwenden, sollten sie gut funktionieren.

Auch ist es besser, einige Schlüsselaustauschprotokoll, wie Diffie-Hellman zu verwenden. Sowohl der OpenSSL-Wrapper von Ruby als auch die Crypto-Lib von Java unterstützen dies. Es ist eine sicherere Methode, Schlüssel pro Sitzung zu generieren.

PS. Ihr Code, so wie Sie ihn haben, scheint für eine eigenständige Ausführung geschrieben zu sein. Ihr Java-Code für die Decodierung geht beispielsweise davon aus, dass Ihre Zeichenfolge mit der encode-Methode der gleichen Instanz codiert wurde. Denn Ihre decode Methode verwendet IV, die in encode Methode (ivBytes) initialisiert wurde.

+0

Dank @Uzbekjon, ich muss das Schlüsselaustauschprotokoll versuchen, ab sofort, wenn ich versuche, eine verschlüsselte Nachricht von der Java-App zu entschlüsseln, bekomme ich einen Fehler, der diesen falschen letzten Block sagt. Ich kann nicht herausfinden, wie beide die gleiche codierte Nachricht geben. Werde deinen Ansatz versuchen und es hier aktualisieren. – sahil

+0

Wenn das Problem im letzten Block liegt, kann dies an den unterschiedlichen Füllzeichen in Ruby und Java liegen. Du solltest das untersuchen. – Uzbekjon

+0

Es gibt noch eine Sache, von der ich nicht sicher bin, ist, in Java verwendet es iv-Schlüssel, also habe ich versucht, den iv-Wert zu bekommen und benutzte es in Ruby als, cipher.iv = same_key, plus sogar der in Ruby verwendete Schlüssel sagt es es ist zu kurz, also habe ich es mit SHA256 in 256 Bit konvertiert, was ich in Java nicht weiß. – sahil