【发布时间】:2016-08-08 20:43:12
【问题描述】:
我用 Java 编写了一个基本的文本加密程序。 (是的,我知道它使用欧洲央行......)
我的程序在 Linux 上运行良好。我将它编译为JAR 文件,这在 Linux 上也可以正常工作。问题是,当我在 Windows 上运行文件时,它会抛出异常,同时使用 same 密钥解密 same text 在 Ubuntu 上运行。
我不知道从哪里开始调试,甚至不知道在 Google 上使用什么搜索词。我完全不知所措。 我认为 Java 是跨平台的。
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class Application
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
String textToEncrypt = "Hello World";
String textToDecrypt;
String textToDecryptAscii;
String result;
int operation;
Cipher cipher = null;
try {
cipher = Cipher.getInstance("AES");
} catch (NoSuchAlgorithmException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//String key = "Bar12345Bar12345"; // 128 bit key
String key = null;
BASE64Encoder asciiEncoder = new BASE64Encoder();
BASE64Decoder asciiDecoder = new BASE64Decoder();
System.out.printf("Enter:\n1 for encryption\n2 for decryption\n\nChoice: ");
operation = input.nextInt();
input.nextLine();
if (operation == 1)
{
try
{
System.out.print("Enter a 128-bit key to be used for encryption: ");
key = input.nextLine();
if(key.length() != 16)
{
while(key.length() != 16)
{
System.out.print("You need to enter a *128-bit* key: ");
key = input.nextLine();
}
}
System.out.printf("\n---------\n\nText to encrypt: ");
textToEncrypt = input.nextLine();
//Create key and cipher
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
//Cipher cipher = Cipher.getInstance("AES");
//encrypt the text
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b: encrypted)
{
sb.append((char)b);
}
// the encrypted String
String enc = sb.toString();
//System.out.println("encrypted:" + enc);
String asciiEncodedEncryptedResult = asciiEncoder.encodeBuffer(enc.getBytes());
asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.replace("\n", "").replace("\r", "");
System.out.println("Encrypted text: " + asciiEncodedEncryptedResult);
//System.out.printf("\n------------------------------\nDecrypted text: " + asciiEncodedEncryptedResult + "\n------------------------------\n\n\n");
}
catch(Exception e)
{
e.printStackTrace();
}
}
else if (operation == 2)
{
System.out.printf("\n---------\n\nText to decrypt: ");
textToDecryptAscii = input.nextLine();
System.out.print("Enter the 128-bit decryption key: ");
key = input.nextLine();
if(key.length() != 16)
{
while(key.length() != 16)
{
System.out.print("You need to enter a *128-bit* key: ");
key = input.nextLine();
}
}
byte[] decodedBytes = null;
try
{
decodedBytes = asciiDecoder.decodeBuffer(textToDecryptAscii);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//System.out.println("decodedBytes " + new String(decodedBytes));
textToDecrypt = new String(decodedBytes);
//Convert the string to byte array
//for decryption
byte[] bb = new byte[textToDecrypt.length()];
for (int i=0; i<textToDecrypt.length(); i++)
{
bb[i] = (byte) textToDecrypt.charAt(i);
}
//decrypt the text
Key aesKey = new SecretKeySpec(key.getBytes(), "AES");
try
{
cipher.init(Cipher.DECRYPT_MODE, aesKey);
}
catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String decrypted = null;
try
{
decrypted = new String(cipher.doFinal(bb));
}
catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.printf("\n------------------------------\nDecrypted text: " + decrypted + "\n------------------------------\n\n\n");
}
}
}
【问题讨论】:
-
你得到什么异常?一个可能的问题是将 String 转换为 byte[]。
String.getBytes()会在系统属性中使用file.encoding,这个值在不同的环境中可能会有所不同。 -
@beckyang -
javax.crypto.BadPaddingException: Given final block not properly padded -
不要将原始字节附加到字符串。这会给您带来各种编码问题。使用
= asciiEncoder.encodeBuffer(encrypted);进行解密使用decodedBytes而不是字符串和密钥,请确保在base64 中输出/输入它(或使用密码派生)。当您的密钥是 ascii 时,它很弱,但不应该是互操作的问题。
标签: java linux windows exception jar