不解密我所隐藏的东西 [英] not decrypting what I crypted

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

问题描述

我有一个奇怪的问题...

I have a weird problem...

根据我的解决方案将硬编码的文件解密为byte []

所以,我写了一个小的Cypher类来帮助解密/解密...它用于模拟在某个地方硬编码的密钥和另一个存储在其他地方的另一个预先加密的密钥。但是这有点不相关的atm。

So, I wrote a small Cypher class to help out with crypting/decrypting... It used to mock-up a key hardcoded at some place and another pre-crypted key stored somewhere else. But that's somewhat irrelevant atm.

这个加密过程如下所示:

the crypting process went like this:


  • 检索硬编码的字节数组

  • 使用它解密key2

  • 使用key2解密数据

  • use key1进一步解密数据

  • 已解密数据

  • retrieve the hardcoded byte array
  • use it to decrypt key2
  • use key2 to decrypt data
  • use key1 to further decrypt data
  • have decrypted data

我正在将加密数据存储为十六进制-string,使用这两个函数来进出那里

I was storing the crypted data as a hex-string, used these two functions to get in-out of there

private static String byteArrayToHexString(byte[] b)
{
    StringBuffer sb = new StringBuffer(b.length * 2);
    for (int i = 0; i < b.length; i++)
    {
        int v = b[i] & 0xff;
        if (v < 16)
        {
            sb.append('0');
        }
        sb.append(Integer.toHexString(v));
    }
    return sb.toString().toUpperCase();
}

private static byte[] hexStringToByteArray(String s)
{
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++)
    {
        int index = i * 2;
        int v = Integer.parseInt(s.substring(index, index + 2), 16); //THIS LINE
        b[i] = (byte) v;
    }
    return b;
}

这工作完美无缺;其实它的工作非常好,我在我的实际项目中实现了这一点。由于我没有彻底测试,因为这个项目没能运行。

That worked flawlessly; in fact it worked so good that I implemented it in my real project. The project failed to run due to the fact that i didn't thoroughly test.

将它解密/解密几乎所有文件除了一个 - 我想解密。

Turns out it crypts/decrypts pretty much all files OK except one - that one doesn't want to decrypt.

我已经精确定位了这个问题 - 这行抛出一个IllegalNumberFormat异常;在某些时候,我熟悉了这个 http://bugs.sun.com/ bugdatabase / view_bug.do?bug_id = 6259307 以及。如果有人描述了一种方法来绕过一个长度为2的字符串转换为四个字节,抛出一个IllegalNumberFormatException。

I have pinpointed the issue however - THIS line throws an IllegalNumberFormat exception; at some point i got acquainted with this http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307 as well. I would and can revert to this method if someone describes a way to bypass a case when a string of length 2 is converted to four bytes which throw an IllegalNumberFormatException.

我认为,由于我无法解码文件(显然不能在这里分享你们来试试),我需要改变它,使其运输安全。输入Base64Coder类编码到base64字符串...

So, I figured that since I cannot decode a file (and obviously cannot share it here for you guys to try out) I needed to transform it somehow to make it transport-safe. Enter the Base64Coder class which encodes to base64 strings...

似乎已经引入了一个新的问题 - 填充正在被消除。

That seemed to have introduced a new issue - padding was getting effed up.

问题很简单 - 我做错了什么?我需要符合这些数据,它必须能够正确和平等地进行隐藏/解密。我想要一个关于最轻量级解决方案的提案,最少的复制/粘贴...伪代码不会在这里做的。

The question is simple - what am I doing wrong? I need to conform to this data and it has to be able to crypt/decrypt properly and equally. I'd like a proposal on the most light-weight solution possible with least copy/pasting... pseudocode won't do the trick here.

m做...现在.... ...

Here's what I'm doing now....

public static char[] encrypt2(byte[] value) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(true);
    System.err.println("encrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters());
    byte[] encrypted = cipher.doFinal(value);

    SecretKeySpec key2 = getSecretKeySpec(false);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.ENCRYPT_MODE, key2, cipher.getParameters());
    byte[] encrypted2 = cipher.doFinal(encrypted);

    return Base64Coder.encode(encrypted2);
}

public static byte[] decrypt2(char[] message) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(false);
    System.err.println("decrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key1);
    byte[] decrypted = cipher.doFinal(Base64Coder.decode(message));

    SecretKeySpec key2 = getSecretKeySpec(true);
    cipher = Cipher.getInstance(CRYPTOSYS);
    cipher.init(Cipher.DECRYPT_MODE, key2);
    byte[] decrypted2 = cipher.doFinal(decrypted);

    return decrypted2;
}

请注意,密钥目前已完全暴露(硬编码)以进行测试。

Note that keys are currently fully-exposed (hardcoded) for testing purposes.

这是我的测试用例

public static void main(String... args) throws Exception
{
    //      byte[] data = "hello".getBytes();
    File PEM = new File(PATH_TO_FILES + SOURCE_PEM);
    File DER = new File(PATH_TO_FILES + SOURCE_DER);
    File cryptoPEM = new File(PATH_TO_FILES + "cryptopem");
    File cryptoDER = new File(PATH_TO_FILES + "cryptoder");

    byte[] cryptokey = encryptA(ASSET_KEY);
    System.out.println(new String(cryptokey));

    //pem key
    System.out.println("PEM");
    byte[] data = getBytesFromFile(PEM);
    char[] crypted = encrypt2(data);
    //      FileOutputStream fos = new FileOutputStream(cryptoPEM);
    FileWriter fw = new FileWriter(cryptoPEM);
    fw.write(crypted);
    fw.flush();

    //der key
    System.out.println("DER");
    data = getBytesFromFile(DER);
    crypted = encrypt2(data);
    fw = new FileWriter(cryptoDER);
    fw.write(crypted);
    fw.flush();

    //opentext
    System.out.println("checking PEM...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoPEM));
    byte[] decrypted = decrypt2(crypted,  false);
    byte[] decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(PEM), decryptedData)) { throw new Exception("PEM Data was not decrypted successfully"); }

    System.out.println("checking DER...");
    crypted = Base64Coder.encode(getBytesFromFile(cryptoDER));
    decrypted = decrypt2(crypted,  false);
    decryptedData = decrypted;

    if (!Arrays.equals(getBytesFromFile(DER), decryptedData)) { throw new Exception("DER Data was not decrypted successfully"); }
}

我现在得到一个InvalidBlockSizeException ....请,某人对此,我只是想要这样工作...

And I'm getting an InvalidBlockSizeException now.... Please, someone shed some light on this, I just want this to work...

替换key2为IV以后在AES / CBC / PKCS5Padding中使用是我正在考虑的一个选择。除了加密的第二步,基本上什么都不会改变。理论上和美学上我会保持一致 - 除非有更好的解决方案被描述。

Replacing 'key2' for an IV to be later used in a "AES/CBC/PKCS5Padding" is an option I'm considering right now. Essentially nothing will change except the second step of encrypting. Theoretically and metodically I'd keep things the same - unless of course a better solution is described.

最后我想指出这是一个程序员问题,而不是一个IT安全学生的问题,所以正确的代码被重视的不仅仅是理论上的反应,涵盖了不可能的缘故。

At the end I'd like to point out that this is a programmer question, not a IT security-student question so proper code is valued more than a theoretical response that covers unlikely fringe cases.

编辑:
好​​吧,我可以不要给你导致IllegalNumberFormatException的数字,因为我今天早上丢失了代码。我似乎不能复制这个问题,所以我猜想这个部分是没有用的。

well, I can't give you the numbers that cause the IllegalNumberFormatException because I lost the code from this morning. I can't seem to replicate the issue so I guess trying to figure that part is of no use.

这是样本测试的输出:

encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
5@��_׵G�j��!�c;D�i�lR?z�j\
PEM
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
DER
encrypt():  javax.crypto.spec.SecretKeySpec@15dd7
checking PEM...
decrypt():  javax.crypto.spec.SecretKeySpec@15c78
Exception in thread "main" javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

这意味着Base64有点搞砸了

which means that Base64 is kinda messing it up...

推荐答案

今天早上检查了代码后,调整了一点,让它工作。

After reviewing the code this morning and tweaking a little bit I got it to work.

public static byte[] encrypt2(byte[] value) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(true);
    System.err.println("encrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, key1, cipher.getParameters());
    byte[] encrypted = cipher.doFinal(value);

    SecretKeySpec key2 = getSecretKeySpec(false);
    System.err.println("encrypt():\t" + key2.toString());
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, key2, new IvParameterSpec(getIV()));
    byte[] encrypted2 = cipher.doFinal(encrypted);

    return encrypted2;//Base64Coder.encode(encrypted2);
}

public static byte[] decrypt2(byte[] message, boolean A) throws GeneralSecurityException, IOException
{
    SecretKeySpec key1 = getSecretKeySpec(false);
    System.err.println("decrypt():\t" + key1.toString());
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, key1, new IvParameterSpec(getIV()));
    byte[] decrypted = cipher.doFinal(message);

    SecretKeySpec key2 = getSecretKeySpec(true);
    System.err.println("decrypt():\t" + key2.toString());
    cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, key2);
    byte[] decrypted2 = cipher.doFinal(decrypted);

    return decrypted2;
}

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

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