请帮助我:(,我在这篇帖子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
它们应该相同,为什么不同?
答案 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,不应在实际的生产代码中使用。