Java AES解密问题 [英] Java AES Decrypting problem

查看:210
本文介绍了Java AES解密问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经完成了使用以下标准对已经加密的Java解密文件:



具有128位密钥,ECB模式和PKCS7的AES加密算法填充。
加密的文件格式为:
- 第一个字节为十六进制0x31 - 指定使用的加密方法(1用于AES)
- 后跟输入文件的加密字节



我还必须下载文件,所以这里是我到目前为止的尝试:



下载代码,我跳过这里的第一个字节为它不是必需的且未被加密:






  final String PATH =/ sdcard /+ IMEI +.xml; //将下载的文件放在这里
try {
URL url = new URL(context.getString(R.string.xml_feed)+ IMEI +.xml);
enc_File = new File(PATH);
long startTime = System.currentTimeMillis();

/ *打开与该URL的连接。 * /

URLConnection ucon = url.openConnection();

/ *
*定义从URLConnection读取的InputStream。
* /
InputStream is = ucon.getInputStream();

BufferedInputStream bis = new BufferedInputStream(is);

/ *
*读缓冲区的字节,直到没有更多的内容读取(-1)。 * /

ByteArrayBuffer baf = new ByteArrayBuffer(50);

int current = 0;
bis.skip(1);
while((current = bis.read())!= -1){

baf.append((byte)current);

}

/ *将读取的字节转换为字符串。 * /

FileOutputStream fos = new FileOutputStream(enc_File);
fos.write(baf.toByteArray());
fos.close();

} catch(IOException e){

}

}






这给我下载的加密文件,所以我尝试使用以下代码解密该文件:






  String bytes = toHex(16位密钥); 
Key skeySpec = new SecretKeySpec(toByte(bytes),AES);
密码c = Cipher.getInstance(AES / ECB / PKCS7Padding);

byte [] buf = new byte [1024];


//读取的字节将被解密

InputStream inCipher = new FileInputStream(enc_File);
OutputStream outCipher = new FileOutputStream(cipherFile);
c.init(Cipher.DECRYPT_MODE,skeySpec);
inCipher = new CipherInputStream(inCipher,c); //读取解密的字节并将明文写入
int numRead = 0;

while((numRead = inCipher.read(buf))> = 0){
outCipher.write(buf,0,numRead);
}
outCipher.close();






上面应该给我一个解密的数据新的文件。



这里是在代码中使用的util方法,用于为SecretKeySpec创建密钥的Byte格式






  public static byte [] toByte(String hexString){
int len = hexString.length()/ 2;
byte [] result = new byte [len]; (int i = 0; i result [i] = Integer.valueOf(hexString.substring(2 * i,2 * i + 2),16).byteValue ();
返回结果;
}

public static String toHex(byte [] buf){
if(buf == null)
return;
StringBuffer result = new StringBuffer(2 * buf.length); (int i = 0; i< buf.length; i ++){
appendHex(result,buf [i]);

}
return result.toString();
}
private final static String HEX =0123456789ABCDEF;
private static void appendHex(StringBuffer sb,byte b){
sb.append(HEX.charAt((b>> 4)& 0x0f))。append(HEX.charAt(b& 0x0f ));
}

public static String toHex(String txt){
return toHex(txt.getBytes());
}
public static String fromHex(String hex){
return new String(toByte(hex));
}






以下例外:

  10-12 11:19:26.337:WARN / System.err(5376):java.io. IOException:解密中的最后一个块不完整

加密文件下载不错,解密运行,但是我得到上面例外和检查应该被解密的文件揭示文件的第一行解密正确,然后下一个几行的小部分,然后返回垃圾为其余。



我被困在这里现在不知道在哪里寻找问题,有人可以帮助吗?或者指出可能导致异常的方向?



附加信息:

  10-12 15:30:37.291:WARN / System.err(6898):在com.mypackage.net.SettingsProvisioner.getRoutingDoc(SettingsProvisioner.java:217)

上述行来自日志cat(stacktrace)中的异常



它显示异常发生在这一行代码:

  while((numRead = inCipher .read(buf))> = 0){


解决方案

没有完整的堆栈跟踪,调试很困难,因为出于安全考虑,如果您不能将其发布到此处(显而易见),请尝试使用堆栈跟踪分析器(如IBM stackanalyzer)或 lady4j



分析工作适用于各种开发(包括Android)


I have been tasked with decrypting a file in Java that has been encrypted using the following criteria:

AES encryption algorithm with 128-bit key, ECB mode and PKCS7 padding. The encrypted file format is: - first byte is hex 0x31 – specifying encryption method used (1 for AES) - followed by the encrypted bytes of the input file

I must also download the file, so here is my attempt so far:

The download code, I skip the first byte here as it is not required and is not encrypted:


final String PATH = "/sdcard/" + IMEI + ".xml";  //put the downloaded file here
        try {
            URL url = new URL(context.getString(R.string.xml_feed) + IMEI + ".xml");
            enc_File = new File(PATH);
            long startTime = System.currentTimeMillis();

            /* Open a connection to that URL. */

            URLConnection ucon = url.openConnection();

            /*
             * Define InputStreams to read from the URLConnection.
             */
            InputStream is = ucon.getInputStream();

            BufferedInputStream bis = new BufferedInputStream(is);

            /*
             * Read bytes to the Buffer until there is nothing more to read(-1).             */

            ByteArrayBuffer baf = new ByteArrayBuffer(50);

            int current = 0;
            bis.skip(1);
            while ((current = bis.read()) != -1) {

                baf.append((byte) current);

            }

            /* Convert the Bytes read to a String. */

            FileOutputStream fos = new FileOutputStream(enc_File);
            fos.write(baf.toByteArray());
            fos.close();

        } catch (IOException e) {

        }

    }


This gives me the encrypted file downloaded, So I then try to decrypt this file using the following code:


         String bytes = toHex("the 16 bit key");
            Key skeySpec = new SecretKeySpec(toByte(bytes), "AES");
            Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding");  

            byte[] buf = new byte[1024]; 


            // Bytes read from in will be decrypted 

            InputStream inCipher = new FileInputStream(enc_File);
            OutputStream outCipher = new FileOutputStream(cipherFile);
            c.init(Cipher.DECRYPT_MODE, skeySpec);
            inCipher = new CipherInputStream(inCipher, c); // Read in the decrypted bytes and write the cleartext to out 
            int numRead = 0;            

                    while ((numRead = inCipher.read(buf)) >= 0) {
                          outCipher.write(buf, 0, numRead);
                } 
                outCipher.close(); 


the above should give me the decryted data in a new file.

And here are the util methods used in that code to create the Key in Byte format for the SecretKeySpec


public static byte[] toByte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}

public static String toHex(String txt) {
    return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
    return new String(toByte(hex));
}


However this currently gives me the following exception:

10-12 11:19:26.337: WARN/System.err(5376): java.io.IOException: last block incomplete in decryption

The encrypted file downloads fine, the decrytption runs but I get the above exception and checking the file that should be decrypted reveals that the first line of the file decrypted properly and then small parts of the next couple of lines but then returns junk for the rest.

I'm stuck at this now not knowing where to look for the problem, can anybody help? Or point me in the direction of what may be causing the exception?

Additional info:

10-12 15:30:37.291: WARN/System.err(6898):     at com.mypackage.net.SettingsProvisioner.getRoutingDoc(SettingsProvisioner.java:217)

The above line is from the exception in the log cat (stacktrace)

And it shows that the exception is occuring at this line of code:

while ((numRead = inCipher.read(buf)) >= 0) {

解决方案

Without the full stacktrace it is dificult to debug we would have to recompile your code, if you can not post it here for security reasons (obvious) try a stacktrace analyzer like the IBM stackanalyzer or lady4j

The analyzer works for everykind of development (Android included)

这篇关于Java AES解密问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆