我用Java编写了一个基本的文本加密程序。 (是的,我知道它使用的是ECB ......)
我的程序在Linux上正常运行。我将它作为JAR
文件编译,并且在Linux上也可以正常工作。问题是,当我在Windows 上运行文件时,它会抛出异常,同时使用相同的密钥解密相同的文字 ,适用于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");
}
}
}
答案 0 :(得分:1)
由于Linux / Unix和Windows之间的CRLF存在差异,我在加密之前就看到了这一点。这两个操作系统完全不同地看到了回车换行和换行。
您可能需要使用Ant和fixcrlf步骤将代码编译到jar文件中:
DECLARE @StudentGrades TABLE(StudentId INT, ClassId INT, Grade DECIMAL(4,2))
-- Sample Entries:
INSERT INTO @StudentGrades
(StudentId, ClassId, Grade)
VALUES (1, 1, 60.0), (1, 2, 70.0), (2, 1, 75.0), (2, 2, 90.0);
-- Check table values.
SELECT * FROM @StudentGrades;
-- This is the report you were looking for.
SELECT StudentId, CONVERT(DECIMAL(4,1), AVG(Grade)) As [GPA]
FROM @StudentGrades
GROUP BY StudentId
ORDER BY GPA Desc; <---- EDITED BY FOXDONUT (GPA in descending order)
此外,它可能不是您的代码...如果您输入的文本没有正确的CRLF编码,您的加密也将失败。
对于它的价值,下面是你的代码的删节版本,跳过操作...它只是接受密钥,然后加密然后转换并在一个流中解密所有...我厌倦了输入相同的操作,相同的键等...
无论如何,以下代码在没有BASE64编码器,解码器的情况下工作......我无法使用BASE64。尽管测试结果显示BASE64“似乎”正在工作,因为我在解码器之后得到了正确的加密文本,但它仍然继续抛出错误。
但是,如果你从图片中取出BASE64编码器和解码器,加密/解密工作正常...另外,我在那里添加了几个关键的.trim(),因为我看到在字符串中引入了隐形CRLF组件。
<fixcrlf
srcdir="${dir.prj.work}"
eol="dos"
includes="**/*"
/>
示例输出:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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 Application() {
// TODO Auto-generated constructor stub
}
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) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
}
//String key = "Bar12345Bar12345"; // 128 bit key
String key = null;
//byte[] 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();
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.println ( "128-bit encryption key.......................["+key+"] length ["+key.length ()+"]");
System.out.printf ( "Text to encrypt..............................[");
//System.out.printf("\n---------\n\nText to encrypt: ");
textToEncrypt = input.nextLine();
System.out.println ( "Text to encrypt..............................["+textToEncrypt+"] length ["+textToEncrypt.length ()+"]");
//Create key and cipher
Key aesKey = new SecretKeySpec(key.trim().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 text...............................["+enc+"] length ["+enc.length ()+"]");
//System.out.println("encrypted:" + enc);
//String asciiEncodedEncryptedResult = asciiEncoder.encodeBuffer(enc.getBytes()).trim ();
String asciiEncodedEncryptedResult = enc.trim ();
System.out.println ( "Encoded text.................................["+asciiEncodedEncryptedResult+"] length ["+asciiEncodedEncryptedResult.length ()+"]");
//asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.replace("\n", "").replace("\r", "");
asciiEncodedEncryptedResult = asciiEncodedEncryptedResult.trim ();
System.out.println ( "Encrypted text...............................["+asciiEncodedEncryptedResult+"] length ["+asciiEncodedEncryptedResult.length ()+"]");
//byte[] decodedBytes = null;
//try {
// decodedBytes = asciiDecoder.decodeBuffer(asciiEncodedEncryptedResult);
//}
//catch (IOException e1) {
// e1.printStackTrace();
//}
//System.out.println ( "Decoded Bytes................................["+decodedBytes+"] length ["+decodedBytes.length+"]");
//textToDecrypt = new String(decodedBytes);
textToDecrypt = asciiEncodedEncryptedResult;
System.out.println ( "Text to Decrypt..............................["+textToDecrypt+"] length ["+textToDecrypt.length()+"]");
//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 = null;
String decrypted = null;
try {
//aesKey = new SecretKeySpec(key.trim ().getBytes (), "AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
decrypted = new String(cipher.doFinal(bb));
}
catch (InvalidKeyException e) {
e.printStackTrace();
}
catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
catch (BadPaddingException e) {
e.printStackTrace();
}
catch ( Exception ltheXcp ) {
ltheXcp.printStackTrace ();
}
if ( decrypted != null ) {
System.out.println ( "Decrypted text...............................["+decrypted+"] length ["+decrypted.length ()+"]");
}
else {
System.out.println ( "Decrypted text...............................["+decrypted+"] length []");
}
}
catch ( Exception ltheXcp ) {
ltheXcp.printStackTrace ();
}
}
}
最重要的是,BASE64编码器/解码器中有“某些东西”导致解密失败......它以某种方式改变了按位字符,这是我用System.out.println()看不到的。 ..也许十六进制输出可能会显示...