无法解密来自文本文件的密文,对称密钥工具。 在java中

所以基本上我的程序从用户选择的文本文件中加密/解密字符串。 他可以选择五种算法中的一种。 问题是当我用例如创建密文时。 AES,然后将此密文保存到文本文件,并希望解密它以获取它不起作用的原始字符串。 有人可以指出问题出在哪里吗?

例如:如果我使用AES加密String:“Hello World !!” 我得到这个密文:“1za7slAXv2KZvDlVZlzu / A ==”然后我将它保存到.txt并使用第二种方式进行解密以获得“Hello World !!” 背部。 但结果很糟糕。

我的方法好吗? 有更好的方法吗?

忘记添加导入:抱歉以前的格式。

import java.io.*; import java.util.Scanner; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.KeyGenerator; import java.security.spec.KeySpec; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.BadPaddingException; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.spec.InvalidKeySpecException; import javax.crypto.NoSuchPaddingException; import javax.crypto.IllegalBlockSizeException; import java.io.UnsupportedEncodingException; public class sifrovaniRaw { Cipher sifr, desifr; sifrovaniRaw(SecretKey klic, String algoritmus) { try { sifr = Cipher.getInstance(algoritmus); desifr = Cipher.getInstance(algoritmus); sifr.init(Cipher.ENCRYPT_MODE, klic); desifr.init(Cipher.DECRYPT_MODE, klic); } catch (NoSuchPaddingException e) { System.out.println(" NoSuchPaddingException"); } catch (NoSuchAlgorithmException e) { System.out.println(" NoSuchAlgorithmException"); } catch (InvalidKeyException e) { System.out.println(" InvalidKeyException"); } } sifrovaniRaw(String passph) { byte[] sul = { (byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c, (byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99 }; int iterace = 20; try { KeySpec klicSpecifikace = new PBEKeySpec(passph.toCharArray(), sul, iterace); SecretKey klic = SecretKeyFactory.getInstance("PBEWithMD5AndTripleDES").generateSecret(klicSpecifikace); sifr = Cipher.getInstance(klic.getAlgorithm()); desifr = Cipher.getInstance(klic.getAlgorithm()); AlgorithmParameterSpec parametry = new PBEParameterSpec(sul, iterace); sifr.init(Cipher.ENCRYPT_MODE, klic, parametry); desifr.init(Cipher.DECRYPT_MODE, klic, parametry); } catch (InvalidAlgorithmParameterException e) { System.out.println(" InvalidAlgorithmParameterException"); } catch (InvalidKeySpecException e) { System.out.println(" InvalidKeySpecException"); } catch (NoSuchPaddingException e) { System.out.println(" NoSuchPaddingException"); } catch (NoSuchAlgorithmException e) { System.out.println(" NoSuchAlgorithmException"); } catch (InvalidKeyException e) { System.out.println(" InvalidKeyException"); } } public String encryption(String str) { try { byte[] utf8 = str.getBytes("UTF8"); byte[] enco = sifr.doFinal(utf8); return new sun.misc.BASE64Encoder().encode(enco); } catch (BadPaddingException e) { } catch (IllegalBlockSizeException e) { } catch (UnsupportedEncodingException e) { } catch (IOException e) { } return null; } public String decryption(String str) { try { byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str); byte[] utf8 = desifr.doFinal(dec); return new String(utf8, "UTF8"); } catch (BadPaddingException e) { } catch (IllegalBlockSizeException e) { } catch (UnsupportedEncodingException e) { } catch (IOException e) { } return null; } public static void testsecklic() { System.out.println("Testing method using secret key"); System.out.println(""); try { System.out.println("Give a path:"); System.out.println("-----"); System.out.println("for UNIX eg: \"/home/user/text_to_encrypt/decrypt.txt\""); System.out.println("for NT Windows eg: \"C://FileIO//text.txt\""); System.out.println("------"); Scanner scan = new Scanner(System.in); String filepath = scan.next(); File file = new File(filepath); BufferedInputStream bin = null; FileInputStream fin = new FileInputStream(file); bin = new BufferedInputStream(fin); byte[] contents = new byte[1024]; int bytesRead=0; String StringCont; while( (bytesRead = bin.read(contents)) != -1) { StringCont = new String(contents, 0, bytesRead); System.out.print(StringCont); SecretKey aesKlic = KeyGenerator.getInstance("AES").generateKey(); SecretKey desKlic = KeyGenerator.getInstance("DES").generateKey(); SecretKey desedeKlic = KeyGenerator.getInstance("DESede").generateKey(); SecretKey rc2Klic = KeyGenerator.getInstance("RC2").generateKey(); SecretKey blowfishKlic = KeyGenerator.getInstance("Blowfish").generateKey(); StringEncrypter aesEncrypt = new StringEncrypter(aesKlic, aesKlic.getAlgorithm()); StringEncrypter desEncrypt = new StringEncrypter(desKlic, desKlic.getAlgorithm()); StringEncrypter desedeEncrypt = new StringEncrypter(desedeKlic, desedeKlic.getAlgorithm()); StringEncrypter rc2Encrypt = new StringEncrypter(rc2Klic, rc2Klic.getAlgorithm()); StringEncrypter blowfishEncrypt = new StringEncrypter(blowfishKlic, blowfishKlic.getAlgorithm()); String aesEncrypted = aesEncrypt.encrypt(StringCont); String desEncrypted = desEncrypt.encrypt(StringCont); String rc2Encrypted = desedeEncrypt.encrypt(StringCont); String desedeEncrypted = rc2Encrypt.encrypt(StringCont); String blowfishEncrypted = blowfishEncrypt.encrypt(StringCont); String aesDecrypt = aesEncrypt.decrypt(aesEncrypted); String desDecrypt = desEncrypt.decrypt(desEncrypted); String rc2Decrypt = rc2Encrypt.decrypt(desedeEncrypted); String desedeDecrypt = desedeEncrypt.decrypt(rc2Encrypted); String blowfishDecrypt = blowfishEncrypt.decrypt(blowfishEncrypted); //FIRST NON-WORKING WAY of decrypting. System.out.println("Do you want to encrypt[1] or decrypt[2] text ?"); int sifDesif = scan.nextInt(); if(sifDesif == 1) { System.out.println("What cypher do you want to choose?"); System.out.println("AES[1], DES[2], rc2[3], blowfish[4], desede[5]"); int vyber = scan.nextInt(); switch(vyber) { case 1: System.out.println("encrypted : " + aesEncrypted); break; case 2: System.out.println("encrypted : " + desEncrypted); break; case 3: System.out.println("encrypted : " + rc2Encrypted); break; case 4: System.out.println("encrypted : " + blowfishEncrypted); break; case 5: System.out.println("encrypted : " + desedeEncrypted); break; } } else if(sifDesif == 2) { System.out.println("What cypher do you want to choose?"); System.out.println("AES[1], DES[2], rc2[3], blowfish[4], desede[5]"); int vyber = scan.nextInt(); switch(vyber) { case 1:System.out.println("decrypted : " + aesDecrypt); break; case 2:System.out.println("decrypted : " + desDecrypt); break; case 3:System.out.println("decrypted : " + rc2Decrypt); break; case 4:System.out.println("decrypted : " + blowfishDecrypt); break; case 5:System.out.println("decrypted : " + desedeDecrypt); break; } } //SECOND WORKING WAY of decrypting. System.out.println("Algorith used:" + aesKlic.getAlgorithm()); System.out.println("text : " + StringCont); System.out.println("encryption : " + aesEncrypted); System.out.println("decryption text : " + aesDecrypt); System.out.println(); } } catch (NoSuchAlgorithmException e) { System.out.println(" No such Algo"); } catch(FileNotFoundException e) { System.out.println("File not found" + e); } catch(IOException ioe) { System.out.println("Exception while reading the file "+ ioe); } } public static void main(String[] args) { testsecklic(); } 

}

由于您每次都在生成加密密钥,因此程序将无法解密使用其他加密密钥创建的密文。 如果要在程序运行之间重用加密密钥,则需要找到一种方法来保留加密密钥。

以下程序是原始示例的较小版本,除了它使用每个密码加密和解密明文。 我没有访问StringEncrypter类所以我写了一个简单的版本:

 import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; public class EncTest { public static void main(String[] args) throws Exception { System.out.println("Testing method using secret key"); String plaintext = "hello world"; SecretKey aesKlic = KeyGenerator.getInstance("AES").generateKey(); SecretKey desKlic = KeyGenerator.getInstance("DES").generateKey(); SecretKey desedeKlic = KeyGenerator.getInstance("DESede").generateKey(); SecretKey rc2Klic = KeyGenerator.getInstance("RC2").generateKey(); SecretKey blowfishKlic = KeyGenerator.getInstance("Blowfish").generateKey(); StringEncrypter[] ciphers = new StringEncrypter[] { new StringEncrypter(aesKlic, aesKlic.getAlgorithm()), new StringEncrypter(desKlic, desKlic.getAlgorithm()), new StringEncrypter(desedeKlic, desedeKlic.getAlgorithm()), new StringEncrypter(rc2Klic, rc2Klic.getAlgorithm()), new StringEncrypter(blowfishKlic, blowfishKlic.getAlgorithm()) }; byte[][] ciphertexts = new byte[ciphers.length][]; int i = 0; for (StringEncrypter cipher : ciphers) { ciphertexts[i] = cipher.encrypt(plaintext); System.out.println(cipher.getAlgorithm() + " encrypted: " + hexEncode(ciphertexts[i])); i++; } System.out.println(); i = 0; for (StringEncrypter cipher : ciphers) { System.out.println(cipher.getAlgorithm() + " decrypted: " + cipher.decrypt(ciphertexts[i])); i++; } } // Hex encoding lifted from commons-codec private static String hexEncode(byte [] input) { return new String(encodeHex(input)); } private static char[] encodeHex(byte[] data) { int l = data.length; char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = DIGITS[(0xF0 & data[i]) >>> 4 ]; out[j++] = DIGITS[ 0x0F & data[i] ]; } return out; } private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static class StringEncrypter { private final SecretKey key; private final String algorithm; public StringEncrypter(SecretKey key, String algorithm) { this.key = key; this.algorithm = algorithm; } public String getAlgorithm() { return algorithm; } public byte[] encrypt(String input) throws Exception { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(input.getBytes("UTF-8")); } public String decrypt(byte[] input) throws Exception { Cipher cipher = Cipher.getInstance(algorithm); cipher.init(Cipher.DECRYPT_MODE, key); return new String(cipher.doFinal(input)); } } }