0

I am able to read the public and private key from the file directly as file stream convert that to PublicKey and PrivateKey Object. but If load as string it fails.

Working code

    public static RSAPrivateKey getPrivateKey(String filename) throws IOException, GeneralSecurityException {

            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
                    IOUtils.toByteArray(new FileInputStream(filename)));
            return (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
        }

        public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException {
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
                    IOUtils.toByteArray(new FileInputStream(filename)));
            return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec);
        }

public static void main(String[] args) throws JOSEException, ParseException, IOException, GeneralSecurityException {

        String publicKeyPathName = "../public";
        String privateKeyPathName = "../private";
        /// loading from file
         RSAPublicKey publicKey = new MYClass().getPublicKey(publicKeyPathName);
         RSAPrivateKey privateKey = new MYClass().getPrivateKey(privateKeyPathName);
}

Not Working code

public static RSAPrivateKey parsePrivateKey(String content) throws IOException, GeneralSecurityException {
        content = content.replaceAll("\\n", "").replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replace("-----END RSA PRIVATE KEY-----", "");
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(content.getBytes(StandardCharsets.UTF_8));
        return (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
    }

    public static RSAPublicKey parsePublicKey(String content) throws IOException, GeneralSecurityException {
        content = content.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "");
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(content.getBytes(StandardCharsets.UTF_8));
        return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec);
    }
public String getPublicKey() {
        return "-----BEGIN PUBLIC KEY-----\n" 
                + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAswPxKZWJEQ0RVtiaoFIU"
                + "jndalEp2sZF87Cy9IxW1FxxcfDmZRlkMDe+5X1lzpOjFHP8mBZa8vhMjSKbJY2wt"
                + "MyxckbBoTjAIefi34KuD0Q6j9LRt1r1iQ+nMYezk5N83ruqyRHtB4a8AOkw3iE2z"
                + "zA74uAkCzPiYUrAES1I9mVbpxJZf2Ej0px6drkd4OQ2aPnwR13gWTnmqFWV+Xkl6"
                + "WapMArewaAUXU9zDqjn4ZpNCkgx6m4CK7PDt+VgYUi+sjI0WzPIb0FMDTYSe1iX6"
                + "mfIabvoetxUmtyQgu4RfHIiOF0no6VEPh31of2B+KZX2OjHKjyKBGUxUkDLm+J2J" 
                + "CwIDAQAB\n"
                + "-----END PUBLIC KEY-----";
    }

    public String getPrivateKey() {
        return "-----BEGIN RSA PRIVATE KEY-----\n"
                + "MIIEowIBAAKCAQEAswPxKZWJEQ0RVtiaoFIUjndalEp2sZF87Cy9IxW1FxxcfDmZ"
                + "RlkMDe+5X1lzpOjFHP8mBZa8vhMjSKbJY2wtMyxckbBoTjAIefi34KuD0Q6j9LRt"
+ "1r1iQ+nMYezk5N83ruqyRHtB4a8AOkw3iE2zzA74uAkCzPiYUrAES1I9mVbpxJZf"
+ "2Ej0px6drkd4OQ2aPnwR13gWTnmqFWV+Xkl6WapMArewaAUXU9zDqjn4ZpNCkgx6"
+ "m4CK7PDt+VgYUi+sjI0WzPIb0FMDTYSe1iX6mfIabvoetxUmtyQgu4RfHIiOF0no"
+ "6VEPh31of2B+KZX2OjHKjyKBGUxUkDLm+J2JCwIDAQABAoIBAFj59p4SoyQEeL/P"
+ "vVs+MNV24WCfektb4tmIiyGrIm0wPY/JGTPsAp/SrTKFRYOL5p04/G7+syVOYdU0"
+ "gRiXpgevXvtS0SU7nprxUoOq/EOmoTt5iraXPwY+aMWrd0GC6SxZnu2GzgIcd2KC"
+ "i3+GD323W0wtvmSekydWMWw2nkNeKCL8WE/GqLjigRzdGl+RVviGC+N3IsZZvcf0"
+ "toNXTxXBPgtcYYWV7MOLsFQkk1yvKh0ISncswkjmkRChi8KQ178hbIzeBuDq+jlY"
+ "11epFjNUpyw2Y3jRHHkVSFKFaE6GeBpHMC0ucBJxyRzw19DZ+iPGI2xZBmW+wEOE"
+ "+khw1WECgYEA6ETt3I9zszzytqh5jBma04EM08+aOw9+CVcCLWSC17vRBOiPGJTE"
+ "bHq6Ln7+pjIErSTrlXOH6kPV0nRzmSDncsttmNXLKCuJUR5stVl/gQY4uaGesF/x"
+ "Kk/orw/ddibukXiXHAkduZXC+3Wq4TaYHChUz/QZv/gamPSusi1zBlMCgYEAxU4k"
+ "gJyKLqKfAXsrX0ilyvwkP4siwzORS1GFU5WfMf0E3ZD/3FMjmhjOLX5vnnWcIFtN"
+ "ERungsyHF0AG5o23HTHkEIi2aZWnC2GiYfpEAJuLhkx08aO65o26RxeC7MOAgL1y"
+ "0wC/b8ceIQkQuYbqdrPBywHry7+/vtPbHOggK2kCgYBIv+Y8shXMKyfefFBtyEtN"
+ "Odt5sEmffA++/yiobRXqWmJyhiDj0xze2WXdUFuUVJBQZwL+8Yu9nXeojl7ytHKp"
+ "6vut5jDWqSQ+aygjeR/NmtRDmFKq7bIMzbCUvIRiEHmiyMGTv2s3CKhkuItINSBZ"
+ "mWxPIia6kQxLoj/hgQjJDwKBgGNTU0zrgSS4+RLlzo/JIq1tAVJ72KQr8ZjZESVi"
+ "zSF9HlXsCOIBeIq6shB09fvveQlQ7RsPsORH0joCIXcvIF+yHf201R+SFuXD4Nsy"
+ "AcnMhBC3rKd4pT4rWvsu+tn2EVq+BG/0kGrU8nXu+lxrbt0S4Rwxe2K2xPBr9oI2"
+ "2PsBAoGBAJHPPAire0lHcPi+J8YkVKuzwEfP7NgeLZdtqjiZBCZiLoP8SRm68FJS"
+ "2UpGX4K7rQhx66H6UwXHylBfush56Z8Y9g7PYel83sy+4bqjod1a5TqNBJMkhDQi"
+ "DrQmDIfpFoRYcOyB4+BeF/w7wL+R5ofov4T+0vB3ST+aztphp2G4\n"
+ "-----END RSA PRIVATE KEY-----";
    }

public static void main(String[] args) throws JOSEException, ParseException, IOException, GeneralSecurityException {

 String publicKeyString = new MyClass().getPublicKey();
         RSAPublicKey publicKey = new MyClass().parsePublicKey(publicKeyString);

         String privateKeyString = new MyClass().getPrivateKey();
         RSAPrivateKey privateKey = new
         MyClass().parsePrivateKey(privateKeyString);

}

I tried without removing the first line, and try to read the file as string . none of them or working. tell me the correct way to use this.

The error I am getting is

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205) at java.security.KeyFactory.generatePublic(KeyFactory.java:334) at j.MyClass.parsePublicKey(MyClass.java:136) at j.MyClass.main(MyClass.java:223) Caused by: java.security.InvalidKeyException: invalid key format at sun.security.x509.X509Key.decode(X509Key.java:387) at sun.security.x509.X509Key.decode(X509Key.java:403) at sun.security.rsa.RSAPublicKeyImpl.(RSAPublicKeyImpl.java:84) at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298) at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201) ... 3 more

My usecase is,

read a keys from the db and do the conversion.

vimal prakash
  • 1,503
  • 1
  • 22
  • 38
  • In your replacement code you are using `----- BEGIN PRIVATE KEY -----` but the key has `----- BEGIN RSA PRIVATE KEY -----`. If it contains a pkcs1 key you will need to convert it to pcks8 before loading or use bouncycastle. See http://stackoverflow.com/questions/8290435/convert-pem-traditional-private-key-to-pkcs8-private-key – pedrofb Feb 13 '17 at 15:44
  • @pedrofb sorry about that, I tried this also. -----BEGIN RSA PRIVATE KEY----- , but no luck. – vimal prakash Feb 13 '17 at 16:52

1 Answers1

1

You're using content.getBytes(StandardCharsets.UTF_8) instead of base 64 decoding the text within the PEM header and footer lines (starting with -----).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • after change this to byte[] encoded = Base64.decodeBase64(content); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encoded); , it giving "algid parse error, not a sequence error" :( – vimal prakash Feb 13 '17 at 16:55
  • It's PKCS#1 encoded instead of PKCS#8 encoded, check e.g. [this answer](http://stackoverflow.com/q/7216969/589259) – Maarten Bodewes Feb 13 '17 at 18:39