DESアルゴリズムを使用してJavaで暗号化された暗号化文字列の復号化に問題があります。私は私の主な問題は、私はJavaコードで塩やIVの仕様が表示されないと思う。私は、以下の情報をしているJavaから.NetへのDES暗号化データの復号
: このHexSequenceは私が解読する必要が暗号化されたデータである。9465E19A6B9060D75C3F7256ED1F4D21EDC18BB185304B92061308A32725BE760F1847E3B19C1D3548F61165EA2E785E48F61165EA2E78
アルゴリズム:キーDES/ECB/NoPadding、::DES、パディングTESTKEY123
復号化した後、私は取得する必要があります:550000000018h000000273Al2011112214340600000000000000000000000000
データを暗号化するために使用されるJavaコードは次のようになります。
私は、データを復号化するために、次の.NETのコードを使用しようとしましたpublic class Encryptor {
private SecretKey secretKey;
private Cipher cipher;
public Encryptor(String algorithmName, String paddingName, String key) {
String keyHexCode = StringUtils.convertUnicodeToHexCode(key.getBytes());
try {
byte[] desKeyData = StringUtils.convertHexStringToByteArray(keyHexCode);
DESKeySpec desKeySpec = null;
try {
desKeySpec = new DESKeySpec(desKeyData);
} catch (InvalidKeyException e) {
e.printStackTrace();
}
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithmName);
try {
secretKey = keyFactory.generateSecret(desKeySpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
try {
cipher = Cipher.getInstance(paddingName);
} catch (NoSuchPaddingException e) {
// TODO: handle exception
}
} catch (NoSuchAlgorithmException e) {
// TODO: handle exception
}
}
private void initEncryptor(int mode) {
try {
cipher.init(mode, secretKey);
} catch (InvalidKeyException e) {
// TODO: handle exception
}
}
public String encrypt(String clearText) {
initEncryptor(Cipher.ENCRYPT_MODE);
try {
// Encrypt the cleartext
byte[] encryptedBytes = cipher.doFinal(clearText.getBytes());
return StringUtils.convertUnicodeToHexCode(encryptedBytes).toUpperCase();
} catch (IllegalBlockSizeException e) {
// TODO: handle exception
} catch (BadPaddingException e) {
// TODO: handle exception
}
return "";
}
public String decrypt(String encryptedTextHex) {
byte[] encryptedText = StringUtils.convertHexCodeSequenceToUnicode(encryptedTextHex);
initEncryptor(Cipher.DECRYPT_MODE);
try {
// Decrypt the encryptedTextHex
return new String(cipher.doFinal(encryptedText));
} catch (IllegalBlockSizeException e) {
// TODO: handle exception
} catch (BadPaddingException e) {
// TODO: handle exception
}
return "";
}
}
:
public class URLDecryptor
{
public static string GetValue(string Data)
{
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
byte[] bytes = System.Text.UnicodeEncoding.Unicode.GetBytes("TESTKEY123");
byte[] salt = new byte[8];
byte[] iv = new byte[8];
Rfc2898DeriveBytes password = new Rfc2898DeriveBytes("TESTKEY123", salt);
cryptoProvider.Key = password.GetBytes(8);
cryptoProvider.IV = iv;
cryptoProvider.Padding = PaddingMode.None;
cryptoProvider.Mode = CipherMode.ECB;
MemoryStream memStream = new MemoryStream(convertHexCodeSequenceToUnicode(Data));
CryptoStream cryptoStream = new CryptoStream(memStream, cryptoProvider.CreateDecryptor(cryptoProvider.Key, cryptoProvider.IV), CryptoStreamMode.Read);
StreamReader reader = new StreamReader(cryptoStream);
string value = reader.ReadToEnd;
reader.Close();
cryptoStream.Close();
return value;
}
private static byte[] convertHexCodeSequenceToUnicode(string hexCodeSequence)
{
byte[] bytes = new byte[(hexCodeSequence.Length/2) + 1]; //This is strange
int index = 0;
int count = 0;
while (count < hexCodeSequence.Length) {
string hexCode = hexCodeSequence.Substring(count, 2);
bytes[index] = getHexValue(hexCode);
count += 2;
index += 1;
}
return bytes;
}
public static byte getHexValue(string hexCode)
{
return byte.Parse(hexCode, System.Globalization.NumberStyles.HexNumber);
}
}
奇妙何がそのラインです:
byte[] bytes = new byte[(hexCodeSequence.Length/2) + 1];
データは55バイト長であるが、私は配置する必要がありますそれは56バイトです。が配列に0バイトを追加しますが、これを行わなければ、暗号化ストリームは復号化するデータが短すぎるというエラーをスローします。
この方法で試してみると、私は出力としてゴミだけを取得します。私は空の塩とIVを使用しています。なぜなら、Javaコードがどの塩とIVを使用しているのかわからないからです。私が知らないデフォルト値はありますか?
EDIT:hexCodeのうちのバイトを取得する Javaコード:
private static byte getNegativeValueForHexConversion(String hexCode) {
int i = Integer.parseInt(hexCode, 16);
return (byte) (i > 127 ? i - 256 : i);
}
Javaは符号付きバイトを使用し、.NETがそのすべての機能のための符号なしバイトを使用していますように見えます。これはおそらく問題でしょうか?
コピー&ペーストのエラーがないことを確認しました。私はJavaコードを実行しようとします。データの解読方法を教えてくれるECBが仕様書に明記されました。上記のポストでは、hexStringをバイト配列に変換する関数を追加しました。 – chrixko
OK。これは、DESを使用したECB暗号化の出力ではないため、ECBを使用して復号化することはできません。暗号化するJavaコードを実行するとどうなるのか教えてください... –
Javaコードを実行しようとしましたが、失敗しました。そこで私は入力文字列をもう一度見て、暗号化されたデータが間違っていることを知りました。オリジナルの暗号化されたデータは64バイト長で、うまくいきました。本当にありがとうあなたのポストは私を助けました! – chrixko