【问题标题】:How to parse in memory string to get private and public key RSA如何解析内存字符串以获取私钥和​​公钥 RSA
【发布时间】:2017-07-01 14:50:38
【问题描述】:

我可以直接从文件中读取公钥和私钥,因为文件流将其转换为 PublicKey 和 PrivateKey 对象。但如果作为字符串加载它会失败。

工作代码

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

不工作的代码

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

}

我尝试不删除第一行,并尝试将文件读取为 string 。他们都没有工作。告诉我正确的使用方法。

我得到的错误是

线程“主”java.security.spec.InvalidKeySpecException 中的异常: java.security.InvalidKeyException:无效的密钥格式 sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205) 在 java.security.KeyFactory.generatePublic(KeyFactory.java:334) 在 j.MyClass.parsePublicKey(MyClass.java:136) 在 j.MyClass.main(MyClass.java:223) 原因: java.security.InvalidKeyException:无效的密钥格式 sun.security.x509.X509Key.decode(X509Key.java:387) 在 sun.security.x509.X509Key.decode(X509Key.java:403) 在 sun.security.rsa.RSAPublicKeyImpl.(RSAPublicKeyImpl.java:84) 在 sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298) 在 sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201) ... 3 更多

我的用例是,

从数据库中读取一个键并进行转换。

【问题讨论】:

  • 在您的替换代码中,您使用的是----- BEGIN PRIVATE KEY -----,但密钥有----- BEGIN RSA PRIVATE KEY -----。如果它包含 pkcs1 密钥,则需要在加载或使用 bouncycastle 之前将其转换为 pcks8。见stackoverflow.com/questions/8290435/…
  • @pedrofb 对此感到抱歉,我也试过了。 -----BEGIN RSA PRIVATE KEY-----,但没有运气。

标签: java encryption rsa private-key public-key


【解决方案1】:

您正在使用 content.getBytes(StandardCharsets.UTF_8) 而不是 base 64 解码 PEM 页眉和页脚行中的文本(以 ----- 开头)。

【讨论】:

  • 将其更改为 byte[] encoded = Base64.decodeBase64(content); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encoded); ,它给出“algid 解析错误,而不是序列错误”:(
  • 它是 PKCS#1 编码而不是 PKCS#8 编码,检查例如this answer
猜你喜欢
  • 1970-01-01
  • 2018-09-24
  • 2017-09-08
  • 2012-01-02
  • 2017-12-23
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多