有人可以告诉我如何使用RC4密钥字符串再次创建密钥吗?

时间:2020-07-30 11:39:39

标签: java rc4-cipher

请帮助我:(,我在这篇帖子Converting string to SecretKey中尝试这个答案

但是它似乎不适用于RC4,请告诉我我做错了什么。 这是我的RC4类,位于单独的文件中:

public class RC4 {
    SecretKey k;


    public RC4() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
       KeyGenerator kg = KeyGenerator.getInstance("RC4");
       k = kg.generateKey();
    }

    public byte[] encrypt(final byte[] plaintext) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RC4");  // Transformation of the algorithm
        cipher.init(Cipher.ENCRYPT_MODE, k);
        byte[] cipherBytes = cipher.doFinal(plaintext);
        return cipherBytes;
    }

    public byte[] decrypt(final byte[] ciphertext) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RC4");
          cipher.init(Cipher.DECRYPT_MODE, k);
          byte[] plainBytes = cipher.doFinal(ciphertext);
          return plainBytes;
    }
    
    public SecretKey getK() {
        return k;
    }

    public void setK(SecretKey k) {
        this.k = k;
    }

}

下面的代码也来自main方法中的另一个文件

RC4 rc4Client = new RC4();
SecretKey k = rc4Client.getK();

String encodedK = Base64.getEncoder().encodeToString(k.getEncoded());

//print
System.out.println("Random k: " + k.toString());

byte[] decodedKey = Base64.getDecoder().decode(encodedK);
k = new SecretKeySpec(decodedKey, 0, decodedKey.length, "RC4");

//print
System.out.println("Random k: " + k.toString());

打印输出为:

Random k: javax.crypto.spec.SecretKeySpec@2c97f72b
Random k: javax.crypto.spec.SecretKeySpec@fffe4170

它们应该相同,为什么不同?

2 个答案:

答案 0 :(得分:0)

将k转换为字节数组,然后转换为String:

byte[] kByte = k.getEncoded();
String encodedK = Base64.getEncoder().encodeToString(kByte)

答案 1 :(得分:0)

根据评论。正在运行...

    public static void main( String[] args ) throws NoSuchAlgorithmException {
        KeyGenerator kg = KeyGenerator.getInstance("RC4");
        SecretKey k1 = kg.generateKey();
        String b64k1 = Base64.encode(k1.getEncoded());
        byte[] bk1 = Base64.decode(b64k1);
        SecretKey k2 = new SecretKeySpec( bk1, 0, bk1.length, "RC4");
        String b64k2 = Base64.encode(k2.getEncoded());
        byte[] bk2 = Base64.decode(b64k2);
        System.out.println(k1);
        System.out.println(k2);
        System.out.println(Arrays.toString(bk1));
        System.out.println(Arrays.toString(bk2));
        System.out.println(b64k1);
        System.out.println(b64k2);
    }

给出以下输出:

javax.crypto.spec.SecretKeySpec@d36802be
javax.crypto.spec.SecretKeySpec@1b4e5
[107, -27, -118, -72, 46, -37, -57, -67, -84, 94, 20, 79, 123, 79, -50, 101]
[107, -27, -118, -72, 46, -37, -57, -67, -84, 94, 20, 79, 123, 79, -50, 101]
a+WKuC7bx72sXhRPe0/OZQ==
a+WKuC7bx72sXhRPe0/OZQ==

为澄清起见,k1.toString()和k2.toString()仅取决于Object.toString()default implementation中的对象实例,并且由于k1和k2是不同的对象,因此输出是不同的。实际的密钥材料在接下来的4行中显示为byte [],然后显示为该字节数组的base64编码的String,并且与预期的相等。

请注意,RC4是not considered safe,不应在实际的生产代码中使用。