कभी-कभी, मैं एक रोचक, अजीब चीज को पूरा करता हूं: एन्क्रिप्टेड टेक्स्ट का एक ही ब्लॉक कई अलग-अलग कुंजी का उपयोग करके डिक्रिप्ट किया जा सकता है!अजीब डीईएस व्यवहार - विभिन्न कुंजी का उपयोग करके डिक्रिप्शन सफल होता है
क्या कोई मुझे बता सकता है कि क्या गलत हो रहा है? बहुत बहुत धन्यवाद।
कृपया मुझे ट्रिपल डीईएस/एईएस आदि पर स्विच करने की कोशिश न करें, मैं सिर्फ यह जानना चाहता हूं कि समस्या कहां है - जावा एसडीके को कॉल करने का तरीका, या जावा एसडीके में बग?
नीचे विंडोज 7 लिनक्स बॉक्स में, एक ही परिणाम पर उत्पादन होता है:
D:\>java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
D:\>java DESTest -e 12345678 abcde977
encrypted as [17fd146fa6fdbb5db667efe657dfcb60]
D:\>java DESTest -d 17fd146fa6fdbb5db667efe657dfcb60 abcde977
decryted as [12345678]
D:\>java DESTest -d 17fd146fa6fdbb5db667efe657dfcb60 abcde976
decryted as [12345678]
D:\>java DESTest -d 17fd146fa6fdbb5db667efe657dfcb60 abcde967
decryted as [12345678]
D:\>java DESTest -d 17fd146fa6fdbb5db667efe657dfcb60 abcde867
decryted as [12345678]
D:\>java DESTest -d 17fd146fa6fdbb5db667efe657dfcb60 abcdf867
Exception in thread "main" java.lang.RuntimeException: javax.crypto.BadPaddingEx
ception: Given final block not properly padded
at DESTest.des(DESTest.java:46)
at DESTest.dec(DESTest.java:31)
at DESTest.main(DESTest.java:19)
Caused by: javax.crypto.BadPaddingException: Given final block not properly padd
ed
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at DESTest.des(DESTest.java:44)
... 2 more
D:\>java DESTest -e 12345678 abcde976
encrypted as [17fd146fa6fdbb5db667efe657dfcb60]
D:\>java DESTest -e 12345678 abcde967
encrypted as [17fd146fa6fdbb5db667efe657dfcb60]
D:\>
स्रोत कोड:
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DESTest {
public static void main(String[] args) {
if (args.length < 3) {
System.out.println("usage: java " + DESTest.class.getCanonicalName() + " -e|-d text key");
return;
}
String mode = args[0].trim();
String text = args[1].trim();
String key = args[2].trim();
try {
String s = "-d".equalsIgnoreCase(mode) ? dec(text, key) : enc(text, key);
System.out.println("\n" + ("-d".equalsIgnoreCase(mode) ? "decryted as [" : "encrypted as [") + s + "]");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
private static String enc(String plainText, String key) throws UnsupportedEncodingException {
return new String(encHex(des(plainText.getBytes("UTF-8"), key, Cipher.ENCRYPT_MODE)));
}
private static String dec(String encrypted, String key) throws UnsupportedEncodingException {
return new String(des(decHex(encrypted), key, Cipher.DECRYPT_MODE), "UTF-8");
}
private static byte[] des(byte[] bytes, String key, int cipherMode) {
final String encoding = "UTF-8";
try {
DESKeySpec desKey = new DESKeySpec(key.getBytes(encoding));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// SecretKey securekey = new SecretKeySpec(key.getBytes(encoding), "DES");//same result as the 3 lines above
Cipher cipher = Cipher.getInstance("DES");
SecureRandom random = new SecureRandom();
cipher.init(cipherMode, securekey, random);
return cipher.doFinal(bytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static final char[] HEX_CHARS = "abcdef".toCharArray();
private static String encHex(byte[] bytes) {
final char[] chars = new char[bytes.length * 2];
for (int i = 0, j = 0; i < bytes.length; i++) {
chars[j++] = HEX_CHARS[(0xF0 & bytes[i]) >>> 4];
chars[j++] = HEX_CHARS[0x0F & bytes[i]];
}
return new String(chars);
}
private static byte[] decHex(String hex) {
final int len = hex.length();
final byte[] bytes = new byte[len/2];
for (int i = 0, j = 0; j < len; i++) {
int f = Character.digit(hex.charAt(j), 16) << 4;
j++;
f = f | Character.digit(hex.charAt(j), 16);
j++;
bytes[i] = (byte) (f & 0xFF);
}
return bytes;
}
}
मैंने कोड डीबग किया, पाया कि अलग-अलग कुंजी स्ट्रिंग एक ही सुरक्षितकी (लाइन 39), यानी [9 7, 98, 98, 100, 100, 56, 55, 55] उत्पन्न होगी, वही सुरक्षित है क्योंकि डिक्रिप्शन की सफलता का कारण बनता है । लेकिन मुझे नहीं पता कि अलग-अलग कुंजी समान सुरक्षित क्यों उत्पन्न करेगी, और इससे कैसे बचें? – reqresp