public key to string and then back to public key java

13,438

You need to use Base64 encoding system while converting to String type.
tostring() method uses JVM default encoding which does not support your characters.

PublicKey public_key = CryptographyHelper.ellipticCurveCrypto().getPublic();     
System.out.println("PUBLIC KEY::" + public_key);

//converting public key to byte            
byte[] byte_pubkey = public_key.getEncoded();
System.out.println("\nBYTE KEY::: " + byte_pubkey);

//converting byte to String 
String str_key = Base64.getEncoder().encodeToString(byte_pubkey);
// String str_key = new String(byte_pubkey,Charset.);
System.out.println("\nSTRING KEY::" + str_key);

//converting string to Bytes
byte_pubkey  = Base64.getDecoder().decode(str_key);
System.out.println("BYTE KEY::" + byte_pubkey);


//converting it back to public key
KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
public_key = (ECPublicKey) factory.generatePublic(new X509EncodedKeySpec(byte_pubkey));
System.out.println("FINAL OUTPUT" + public_key);
Share:
13,438
c5564200
Author by

c5564200

Updated on June 08, 2022

Comments

  • c5564200
    c5564200 almost 2 years

    So I have this piece of code which I'm trying to do some conversions in so firstly I generate a public key and print it, and then convert in byte, then to string. After then I am converting it back to bytes, but when I convert it back to bytes the value changes for the byte so the public key generated isn't the same as the top one, as you can see in the output below.

    //generating public key     
    PublicKey public_key = CryptographyHelper.ellipticCurveCrypto().getPublic();
    System.out.println("PUBLIC KEY::" + public_key);
    
    //converting public key to byte            
    byte[] byte_pubkey = public_key.getEncoded();
    System.out.println("\nBYTE KEY::: " + byte_pubkey);
    
    //converting byte to String 
    String str_key = Arrays.toString(byte_pubkey);
    System.out.println("\nSTRING KEY::" + str_key);
    
    //converting string to Bytes
    byte_pubkey = str_key.getBytes();
    System.out.println("BYTE KEY::" + byte_pubkey);
    
    //converting it back to public key
    KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
    public_key = (ECPublicKey) factory.generatePublic(new X509EncodedKeySpec(byte_pubkey));
    System.out.println("FINAL OUTPUT" + public_key);
    

    Output

        PUBLIC KEY::EC Public Key [4d:53:40:86:3f:a8:91:49:b6:27:b5:58:14:b8:8b:f1:ff:8a:78:70]
                X: c8e1028cad7b105814d4a2e0e292f5f7904aad7b6cbc46a5
                Y: 312272321a1ba4ff14caa73b42acb35eb025d9f6fc2ca6b3
    
    
    BYTE KEY::: [B@1a1d6a08
    
    STRING KEY::[48, 70, 48, 16, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 5, 43, -127, 4, 0, 31, 3, 50, 0, 4, -56, -31, 2, -116, -83, 123, 16, 88, 20, -44, -94, -32, -30, -110, -11, -9, -112, 74, -83, 123, 108, -68, 70, -91, 49, 34, 114, 50, 26, 27, -92, -1, 20, -54, -89, 59, 66, -84, -77, 94, -80, 37, -39, -10, -4, 44, -90, -77]
    BYTE KEY[B@37d31475
    Exception in thread "main" java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: Extra data detected in stream
        at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
        at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)
        at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
        at blahblah.Driver.main(Driver.java:44)
    C:\Users\blahblah\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
    BUILD FAILED (total time: 1 second)
    

    I have an error because when I am converting it back to bytes the second time and then when it convert backs to public key it becomes invalid, hence the error.

    Additional Infornmation

    But when I just do this it works fine, but my goal is to first convert the public key to a string somehow, then convert that string to type public key. The only way I can do that is by converting the public key, which is in string type, to a byte type and then converting it back to a public key. I can not convert a string directly to a public key as it won't work.

    • NielsNet
      NielsNet over 5 years
      You should have a look at the charset used when creating and parsing the bytes
    • Rathan Naik
      Rathan Naik over 5 years
      Can u mention which all libraries you are using ?
  • Rathan Naik
    Rathan Naik over 5 years
    I tried using my own implementation for the rest of the missing part, you need to post your entire code and also mention libraries to be on the same page and resolve this issue
  • Sara.a
    Sara.a almost 4 years
    What about the privateKey? I tried this code but it keeps giving me this error: Exception in thread "main" java.security.spec.InvalidKeySpecException: Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSA‌​KeyFactory.java:335) at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePriva‌​te(RSAKeyFactory.jav‌​a:212) at java.base/java.security.KeyFactory.generatePrivate(KeyFactor‌​y.java:390)