Zoopa
Zoopa

Reputation: 11

decrypting a compressed string

I am trying to decrypt this certificate. I zip it before encrypting it since it is big. For decrypting, I am decrypting then unzip it. I would really appreciate any help.

This is the output:

[B@3ac42916

[B@5cad8086 while the output should be the certification string

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

Upvotes: 0

Views: 240

Answers (2)

Joop Eggen
Joop Eggen

Reputation: 109603

It is the Object.toString() of a byte array:

  • Type [ array
  • Type B byte
  • Address @hex object "address"

Java Strings hold internally Unicode, in the form of UTF-16 chars (1 char is two bytes). Hence if there is binary data, byte[], which is actually text in some encoding/Charset, then there happens a conversion:

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

If those bytes are random binary data, there is no guarantee that a conversion is possible; for instance they likely are not UTF-8 conformant. Also there is no guarantee that the conversion back from String to bytes will be correct (as both a special dash and '-' could be mapped to a '-').

So only if you encrypt/decrypt text use String. Then use StandardCharsets.UTF_8 to cover the entire Unicode range.

Otherwise stay with byte[], and use for dumps Arrays.toString:

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

Upvotes: 0

user8097737
user8097737

Reputation:

The problem is that you shouldn't directly convert a byte-array to a String, with toString().

This first mistake is System.out.println(encrypted); and the second is cert.toString() both are using the .toString() from Object which returns a meaningless String.

JavaDoc of Object.toString()

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

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

When you want do display the content of a byte-array better use

System.out.println(Arrays.toString(encrypted));

Also I would change encrypt to

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

and use

byte [] encrypted = encrypt(privateKey, cert);

Upvotes: 1

Related Questions