【问题标题】:Encryption algorithm preferably having an implementation in java加密算法最好在java中实现
【发布时间】:2012-09-13 10:43:13
【问题描述】:

我正在寻找一种对称密钥加密方案来加密我的 12 字节数据。如您所见,它不符合 64 位或 128 位边界,我使用分组加密算法并且我不想填充数据,因为我对加密数据的长度有限制。限制是因为我将使用 base 32 将其转换为不能超过 20 个字符的可打印键。纯文本具有非常可预测的数据模式,因此加密方案应该能够隐藏它。据我了解,伪随机密钥生成是此问题的唯一解决方案,但加密数据的解决方案和解密数据的解决方案彼此不交谈。

【问题讨论】:

    标签: java encryption key encryption-symmetric base32


    【解决方案1】:

    为什么不使用 RC4?密文与明文的大小完全相同 - 在您的情况下为 12 个字节。它带有 Java(5 或更高版本)。这是一个例子:

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import javax.xml.bind.DatatypeConverter;
    
    public class MyArcFour
    {
       public static void main(String [] args) throws Exception
       {
          byte [] key = "MYVERYINSECUREKEY".getBytes("ASCII");
    
          String clearText = "123456789012";
    
          Cipher rc4 = Cipher.getInstance("RC4");
          SecretKeySpec rc4Key = new SecretKeySpec(key, "RC4");
          rc4.init(Cipher.ENCRYPT_MODE, rc4Key);
    
          byte [] cipherText = rc4.update(clearText.getBytes("ASCII"));
    
          System.out.println("clear (ascii)        " + clearText);
          System.out.println("clear (hex)          " + DatatypeConverter.printHexBinary(clearText.getBytes("ASCII")));
          System.out.println("cipher (hex) is      " + DatatypeConverter.printHexBinary(cipherText));
    
          Cipher rc4Decrypt = Cipher.getInstance("RC4");
          rc4Decrypt.init(Cipher.DECRYPT_MODE, rc4Key);
          byte [] clearText2 = rc4Decrypt.update(cipherText);
    
          System.out.println("decrypted (clear) is " + new String(clearText2, "ASCII"));
       }
    }
    

    这会生成以下输出:

    clear (ascii)        123456789012
    clear (hex)          313233343536373839303132
    cipher (hex) is      CBFB9A712E55EBD985C8F2DF
    decrypted (clear) is 123456789012
    

    当然,您会希望使用比示例中更好(更长、更随机)的密钥。

    【讨论】:

    • 谢谢user1657364!但正如我所说,只要密钥保持不变,密文就会变得可预测。我尝试加密“1234DifferentText”并得到 CBFB9A715F0ABA87D98AA68380298E4F46。密文的第一部分保持不变,表示数据模式。
    • 我现在不太了解 RC4,但它是一个流密码,然后是相同的字节,在相同的位置,具有相同的历史(即之前的字节),用相同的密钥,显然应该总是产生相同的加密字节。
    • 尝试此代码时出现错误... java.security.InvalidKeyException: Illegal key size or default parameters
    【解决方案2】:

    您可以使用像 RC4 这样的流密码,但正如您所发现的,您不能重复使用密钥。对于流密码,使用键/随机数(随机数 = 使用一次的数字)组合。随机数可以像 1、2、3、4、... 或日期/时间一样简单,并且需要与密文一起存储。在随机数循环为零并开始重复之前更改密钥。如果您使用日期/时间,请确保时钟的滴答速度足够快,不会重复某个值。

    你有一个长期密钥和一个随机数。每次你想加密某些东西时,对它们进行哈希处理以获得会话密钥:

    sessionKey <- SHA256(longTermKey + nonce)
    

    只使用一次此会话密钥,然后将其丢弃。存储随机数以用于解密。增加一个数字随机数以备下次使用。对于日期/时间随机数,插入一个短暂的延迟以确保时钟已更改。下次使用时,nonce 必须不同。

    当您更改长期密钥时,您需要对所有数据进行解密和重新加密。或者,为您的 nonce 选择一个较大的位大小,并确保您的长期密钥非常安全。

    【讨论】:

      【解决方案3】:

      您想要/需要一个流密码:http://en.wikipedia.org/wiki/Stream_cipher

      【讨论】:

        猜你喜欢
        • 2014-08-26
        • 1970-01-01
        • 2017-07-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-23
        • 2019-04-02
        • 2011-02-12
        • 1970-01-01
        相关资源
        最近更新 更多