当前位置: 首页 > 面试题库 >

不解密我加密的内容

周洋
2023-03-14
问题内容

我有一个奇怪的问题

我的解决方案基于将硬编码文件解密为字节[]

因此,我写了一个小的Cypher类来帮助进行加密/解密…它曾经用来模拟在某个地方进行硬编码的密钥,以及另一个在其他地方存储的预加密密钥。但这与atm无关。

加密过程如下:

  • 检索硬编码的字节数组
  • 用它来解密key2
  • 使用key2解密数据
  • 使用key1进一步解密数据
  • 已解密数据

我将加密的数据存储为十六进制字符串,使用这两个函数来获取数据

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;
}

那完美无瑕。实际上,它是如此出色,以至于我在实际项目中实现了它。该项目由于我没有彻底测试而无法运行。

事实证明,除了一个文件外,几乎所有文件都可以解密/解密,一个文件不想解密。

但是,我已经查明了问题-
此行引发了IllegalNumberFormat异常;在某些时候,我也熟悉此http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6259307。如果有人描述了一种将长度为2的字符串转换为引发IllegalNumberFormatException的四个字节的情况的绕过情况的方法,则我将并且可以恢复为该方法。

因此,我认为由于无法解码文件(并且显然无法在此处共享该文件供您试用),我需要以某种方式对其进行转换以使其传输安全。输入编码为base64字符串的Base64Coder类…

这似乎引入了一个新问题-填充变得烦人了。

问题很简单-
我在做什么错?我需要遵循此数据,并且它必须能够正确且均等地进行加密/解密。我想要一个关于最轻量级解决方案的建议,该方法可能需要最少的复制/粘贴操作……伪代码在这里不会解决问题。

这就是我现在正在做的…

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;
}

请注意,出于测试目的,密钥当前已完全暴露(硬编码)。

这是我的测试用例

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…。请有人对此有所了解,我只是想让它工作…

我现在正在考虑将IV的“ key2”替换为以后在“ AES / CBC /
PKCS5Padding”中使用。基本上,除了加密的第二步之外,什么都不会改变。从理论上和方法上讲,我将保持不变-除非描述了更好的解决方案。

最后,我想指出的是,这是一个程序员的问题,而不是IT安全性学生的问题,因此,正确的代码比对涉及不太可能发生的情况的理论答复的重视程度更高。

编辑:好吧,我不能给您提供导致IllegalNumberFormatException的数字,因为我从今天早上丢失了代码。我似乎无法复制该问题,因此我想尝试弄清楚该部分没有用。

这是样本测试的输出:

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有点搞砸了…


问题答案:

在今天早上检查了代码并进行了一些调整之后,我开始使用它。

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;
}


 类似资料:
  • 我有Java代码片段负责加密和解密,需要在Ruby中转换。在这里张贴之前,我通过了4个链接,但没有运气。 AES-CBC-PKCS5Padding-Encrypt-in-Java-Decrypt-in-Ruby AES-CBC-PKCS5Padding-在Ruby-for-Rails中实现 gist.github.com Ruby中的对称加密算法 为了得到相同的结果,我编写了下面的代码 我的努力:

  • 这是我第一次在这里寻求帮助,我的部门(政府)已经在市场上发布了一些应用程序(Google Play),直到昨天,当我在Nexus上获得Jelly Bean 4.2时,加密和描述一直运行得很好。加密工作正常,它实际上加密了要存储的信息。虽然当解密它时,我得到了一个异常,就像这样:填充块损坏。我已经检查了字符串,并且它与其他设备上的字符串一致(出于测试目的使用相同的密钥),这意味着它完全相同。问题是我

  • 我想根据我在perl中所做的事情用C语言做一个加密/解密程序。编译后的perl程序是2MB,所以我想如果我用C语言编写它,它的可执行大小会更小。 我的问题是,虽然我让它加密,但我无法解密它。自从我上次使用C以来,已经很久了,所以我忘记了很多东西。有人请启发我在这里做错了什么?谢谢。

  • 本文向大家介绍Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签,包括了Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签的使用技巧和注意事项,需要的朋友参考一下 Python3.7 基于 pycryptodome 的AES加密解密、RSA加密解密、加签验签,具体代码如下所示: ps:Python3 RSA加密

  • 我理解哈希和加密之间的区别。我正在寻找一种在Python中实现加密/解密字符串的简单方法。我在网上找到的大多数方法都是关于使用散列算法(MD5-SHA-1等)来进行单向散列。但不幸的是,哈希是不可逆的。有什么建议吗?

  • 问题内容: 我有以下Go代码 输出是 使用以下CryptoJS加密 并且可以用解密 输出是-这是正确的输出 为什么Go会有不同的输出? 问题答案: 请检查您的错误。总是 https://play.golang.org/p/dRLIT51u4I 更具体地说,字节75处的值为,超出了base64可用字符的范围。在ascii中,它是ENQ(查询)字符。至于为什么它最终出现在您的最终base64字符串中,