Reputation: 11
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
Reputation: 109603
It is the Object.toString() of a byte array:
[
arrayB
byte@
hex object "address"Java String
s hold internally Unicode, in the form of UTF-16 char
s (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
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