Frage

Bitte, fragen Sie mich einfach nicht, warum. Ich habe nur diesen Code in .NET, die Verschlüsselung / Strings von Daten entschlüsseln. Ich brauche jetzt ‚genau‘ die gleiche funcionality in Java zu machen. Ich habe mehrere Beispiele versucht, für DESede Krypta, aber keiner von ihnen gibt die gleichen Ergebnisse wie diese Klasse in .net.

Ich auch wenn auf eine .net webserbvice hinter ssl so dass diese beiden Methoden in .net writen zu dienen, aber es ist einfach zu dumm, ohne anstrengend alle posibilities zu tun.

Vielleicht die einige von euch java Menschen mehr im Bereich bezogen sind, werden auf Ihre Köpfe haben, wie es zu machen.

Danke !!!

public class Encryption
{
  private static byte[] sharedkey = {...};
  private static byte[] sharedvector = {...};

  public static String Decrypt(String val)
  {
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    byte[] toDecrypt = Convert.FromBase64String(val);
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, tdes.CreateDecryptor( sharedkey, sharedvector ), CryptoStreamMode.Write);

    cs.Write(toDecrypt, 0, toDecrypt.Length);
    cs.FlushFinalBlock();
    return Encoding.UTF8.GetString(ms.ToArray());
  }

  public static String Encrypt(String val)
  {
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    byte[] toEncrypt = Encoding.UTF8.GetBytes(val);
    MemoryStream ms = new MemoryStream();
    CryptoStream cs = new CryptoStream(ms, tdes.CreateEncryptor( sharedkey, sharedvector ), CryptoStreamMode.Write);
    cs.Write(toEncrypt, 0, toEncrypt.Length);
    cs.FlushFinalBlock();
    return Convert.ToBase64String(ms.ToArray());
  }
}

samle Eingabe / Ausgabe

String plain = "userNameHere:passwordHere";
Console.WriteLine("plain: " + plain);


String encrypted = Encrypt(plain);
Console.WriteLine("encrypted: " + encrypted);
// "zQPZgQHpjxR+41Bc6+2Bvqo7+pQAxBBVN+0V1tRXcOc="

String decripted = Decrypt(encrypted);
Console.WriteLine("decripted: " + decripted); 
// "userNameHere:passwordHere"
War es hilfreich?

Lösung

-Code folgt, aber zuerst ein paar Noten.

  1. Eine andere Initialisierungsvektor muss für jede Nachricht gewählt werden. Hartcodierung der Initialisierungsvektor ist nicht sinnvoll. Die IV sollte zusammen mit dem verschlüsselten Text an den Nachrichtenempfänger gesendet werden (es ist nicht geheim).
  2. Ich habe meine eigene Utility-Klasse für Base-64-Codierung. Sie können stattdessen sun.misc.BASE64Encoder und sun.misc.BASE64Decoder verwenden, verwenden Sie ein Drittanbieter-Bibliothek wie BouncyCastle, oder schreiben Sie Ihre eigenen.
  3. Sie sind mit 2-Key-Triple-DES, wo der erste Schlüssel und der dritte Schlüssel gleich ist. Ich veränderte sharedkey dies widerzuspiegeln, da immer die Java DESede Chiffre ein 192-Bit-Schlüssel erfordert; es ist bis zu dem Schlüssel-Generator der Keying-Option zu behandeln.
  4. A CBC IV nur 64 Bit. Ich habe nur die ersten 64 Bits von sharedvector verwendet.

Diese Klasse soll inter arbeiten mit der C # Version.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Encryption
{

  private static byte[] sharedkey = {
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11, 
    0x12, 0x11, 0x0D, 0x0B, 0x07, 0x02, 0x04, 0x08, 
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
  };

  private static byte[] sharedvector = {
    0x01, 0x02, 0x03, 0x05, 0x07, 0x0B, 0x0D, 0x11
  };

  public static void main(String... argv)
    throws Exception
  {
    String plaintext = "userNameHere:passwordHere";
    String ciphertext = encrypt(plaintext);
    System.out.println(ciphertext);
    System.out.println(decrypt(ciphertext));
  }

  public static String encrypt(String plaintext)
    throws Exception
  {
    Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
    byte[] encrypted = c.doFinal(plaintext.getBytes("UTF-8"));
    return Base64.encode(encrypted);
  }

  public static String decrypt(String ciphertext)
    throws Exception
  {
    Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    c.init(Cipher.DECRYPT_MODE, new SecretKeySpec(sharedkey, "DESede"), new IvParameterSpec(sharedvector));
    byte[] decrypted = c.doFinal(Base64.decode(ciphertext));
    return new String(decrypted, "UTF-8");
  }

}

Ausgabe:

  

zQPZgQHpjxR + 41Bc6 + 2Bvqo7 + pQAxBBVN + 0V1tRXcOc =

     

userNameHere: passwordHere

Andere Tipps

Sie haben ein paar Probleme,

  1. Ihr Schlüssel muss 24 Bytes sein, wenn Sie die gleichen Schlüsselmaterialien sowohl auf .NET und Java generieren möchten.
  2. Die IV muss Blockgrße sein, die 8 Bytes für die Triple-DES ist.
  3. In Java, müssen Sie den Standardmodus und Polsterung spezifizieren, die "DESede / CBC / NoPadding" ist.

Wenn Sie diese Änderungen vornehmen, sollten Sie in der Lage sein, es auf Java-Seite zu entschlüsseln.

Haben Sie sich vergewissert die .NET-Code die gleiche Polsterung als Java-Code verwendet? Ich sehe keine Polsterung im .NET-Code angegeben, deshalb frage ich.

Sie zufällig die Quelle für den Java-Code haben, wird es helfen, Fehler zu finden.

Versuchen Sie, die folgenden. Für die tatsächliche Nutzung, würde ich eine base64-Bibliothek wie commons Codec bekommen oder den Codec verwenden, die mit BouncyCastle kommt

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class Encryption {

    private static SecretKey sharedkey;
    private static byte [] sharedvector;

    static {
        int keySize = 168;
        int ivSize = 8;
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
            keyGenerator.init(keySize);
            sharedkey = keyGenerator.generateKey();

            sharedvector = new byte [ivSize];
            byte [] data = sharedkey.getEncoded();

            int half = ivSize / 2;
            System.arraycopy(data, data.length-half, sharedvector, 0, half);
            System.arraycopy(sharedvector, 0, sharedvector, half, half);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public static void main(String [] args) throws Exception {
        System.out.println(Decrypt(Encrypt("Hello World")));

    }

    public static String Encrypt(String val) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, sharedkey, new IvParameterSpec(sharedvector));

        return new sun.misc.BASE64Encoder().encode(cipher.doFinal(val.getBytes()));
    }

    public static String Decrypt(String val) throws GeneralSecurityException, IOException {
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, sharedkey, new IvParameterSpec(sharedvector));

        return new String(cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(val)));
    }

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top