1

3Desを使用するサードパーティからの値を復号化するのに問題があります。彼らは私にキー、暗号化された値、使用されたモード、そして復号化された値がどうあるべきかを教えてくれましたが、これまでのところ私はポイントaからbに到達する方法を理解できませんでした。問題は彼らが私にくれた鍵に関係していると私は信じています-彼らはそれがクリアテキストの鍵であると言います、しかしそれはまだ何らかの形でさらに変換される必要があると思います。

以下のコードは、値(この場合はAC9C5A46A63FC9EA)を復号化する方法を理解するための最初の試みの例です。

任意の洞察をいただければ幸いです。

import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

public class TripleDes2 {

private static final String UNICODE_FORMAT = "UTF8";
private static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private static final String CIPHER_ALG = "DESede/ECB/Nopadding"; //assuming no padding
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
private byte[] arrayBytes;
private String myEncryptionKey;
private SecretKey key;

public static void main(String args []) throws Exception {
    TripleDes2 td= new TripleDes2();

    String decrypted = td.decrypt("AC9C5A46A63FC9EA");
    System.out.println("expecting: 04286EDDFDEA6BD7");
    System.out.println("found: " + decrypted);
}

public TripleDes2() throws Exception {
    myEncryptionKey = "1032FD2CD64A9D7FA4D061F76B04BFEA";
    arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
    ks = new DESedeKeySpec(arrayBytes);
    skf = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);

    cipher = Cipher.getInstance(CIPHER_ALG);
    key = skf.generateSecret(ks);
}

public String decrypt(String encryptedString) {
    String decryptedText=null;
    try {
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] encryptedText = encryptedString.getBytes();
        byte[] plainText = cipher.doFinal(encryptedText);
        decryptedText= new String(plainText);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return decryptedText;
}
}
4

2 に答える 2

3

などで必要以上に複雑にしていますSecretKeyFactory。しかし、主な問題は、16進数を正しく変換していないことです。

class TripleDES
{

  private final String key;

  public static void main(String... args)
    throws Exception
  {
    TripleDES td = new TripleDES("1032FD2CD64A9D7FA4D061F76B04BFEA");
    String decrypted = td.decrypt("AC9C5A46A63FC9EA");
    System.out.println("expecting: 04286EDDFDEA6BD7");
    System.out.println("found: " + decrypted);
  }

  TripleDES(String key)
  {
    this.key = key;
  }

  public String decrypt(String input)
    throws Exception
  {
    byte[] tmp = h2b(this.key);
    byte[] key = new byte[24];
    System.arraycopy(tmp, 0, key, 0, 16);
    System.arraycopy(tmp, 0, key, 16, 8);
    Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "DESede"));
    byte[] plaintext = cipher.doFinal(h2b(input));
    return b2h(plaintext);
  }

  private static byte[] h2b(String hex)
  {
    if ((hex.length() & 0x01) == 0x01)
      throw new IllegalArgumentException();
    byte[] bytes = new byte[hex.length() / 2];
    for (int idx = 0; idx < bytes.length; ++idx) {
      int hi = Character.digit((int) hex.charAt(idx * 2), 16);
      int lo = Character.digit((int) hex.charAt(idx * 2 + 1), 16);
      if ((hi < 0) || (lo < 0))
        throw new IllegalArgumentException();
      bytes[idx] = (byte) ((hi << 4) | lo);
    }
    return bytes;
  }

  private static String b2h(byte[] bytes)
  {
    char[] hex = new char[bytes.length * 2];
    for (int idx = 0; idx < bytes.length; ++idx) {
      int hi = (bytes[idx] & 0xF0) >>> 4;
      int lo = (bytes[idx] & 0x0F);
      hex[idx * 2] = (char) (hi < 10 ? '0' + hi : 'A' - 10 + hi);
      hex[idx * 2 + 1] = (char) (lo < 10 ? '0' + lo : 'A' - 10 + lo);
    }
    return new String(hex);
  }

}
于 2012-05-16T17:52:27.687 に答える
0

主な問題は、getBytes()を介してバイト配列に変換される16進データを含む文字列の使用法のようです。

16進文字列をそのバイト配列表現に変換するには、 apache.commons.codec.binaryなどの外部ライブラリが必要です。

 myEncryptionKey = "1032FD2CD64A9D7FA4D061F76B04BFEA";
 arrayBytes = Hex.decodeHex(myEncryptionKey.toCharArray());
于 2012-05-16T17:43:20.577 に答える