解密压缩字符串

时间:2017-12-14 08:51:35

标签: java security encryption

我正在尝试解密此证书。我在加密之前将其压缩,因为它很大。对于解密,我正在解密然后解压缩它。我真的很感激任何帮助。

这是输出:

  

[B @ 3ac42916

     

[B @ 5cad8086   而输出应该是认证字符串

package test11;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;

public class Sample {

public static void main(String [] args) throws Exception {
    // generate public and private keys
    KeyPair keyPair = buildKeyPair();
    PublicKey pubKey = keyPair.getPublic();
    PrivateKey privateKey = keyPair.getPrivate();


    GzipUtil zipp = new GzipUtil();
    // encrypt the message
    String hour = "00";
    String certificate="1"+","+"0336"+","+"RSA"+","+"CA 1552"+","+hour+","+pubKey+","+"RSA";
    byte [] cert = GzipUtil.zip(certificate) ;
    byte [] encrypted = encrypt(privateKey, cert.toString());     
    System.out.println(encrypted);  // <<encrypted message>>

    // decrypt the message
    byte[] secret = decrypt(pubKey, encrypted);
  String text= GzipUtil.unzip(secret);
    System.out.println(text);     // This is a secret message
}

public static KeyPair buildKeyPair() throws NoSuchAlgorithmException {
    final int keySize = 2048;
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(keySize);      
    return keyPairGenerator.genKeyPair();
}

public static byte[] encrypt(PrivateKey privateKey, String message) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);  

    return cipher.doFinal(message.getBytes());  
}

public static byte[] decrypt(PublicKey publicKey, byte [] encrypted) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.DECRYPT_MODE, publicKey);

    return cipher.doFinal(encrypted);
}
}

2 个答案:

答案 0 :(得分:1)

问题是你不应该使用toString()直接将字节数组转换为字符串。

第一个错误是System.out.println(encrypted);,第二个错误cert.toString()都使用了来自.toString()的{​​{1}},它返回了无意义的字符串。

Object

的JavaDoc
  

类Object的toString方法返回一个字符串,该字符串由对象为实例的类的名称,符号字符“@”和对象的哈希码的无符号十六进制表示组成。换句话说,此方法返回一个等于值的字符串:

     

getClass()。getName()+'@'+ Integer.toHexString(hashCode())

如果要显示字节数组的内容,请更好地使用

Object.toString()

我也会将System.out.println(Arrays.toString(encrypted)); 更改为

encrypt

并使用

public static byte[] encrypt(PrivateKey privateKey, byte[] message) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.ENCRYPT_MODE, privateKey);  

    return cipher.doFinal(message);  
}

答案 1 :(得分:0)

它是字节数组的Object.toString():

  • 输入[数组
  • 键入B byte
  • 地址@十六进制对象“地址”

Java String以UTF-16 char的形式保存内部Unicode(1个字符是两个字节)。 因此,如果存在二进制数据byte[],在某些编码/ Charset中实际上是 text ,则会发生转换:

Charset charset = Charset.from("Windows-1252");
byte[] bytes = s.getBytes(charset);
String s = new String(bytes, charset);

如果这些字节是随机二进制数据,则无法保证可以进行转换;例如,他们可能不符合UTF-8。 此外,无法保证从String到字节的转换是正确的(因为特殊的破折号和' - '都可以映射到' - ')。

因此,只有加密/解密文本时才使用String。然后使用StandardCharsets.UTF_8覆盖整个Unicode范围。

否则请留在byte[],并用于转储Arrays.toString

Logger.getLogger(MyClass.class.getName()).info("decrypted: {}", Arrays.toString(bytes));