Java中从私钥获取公钥

发布于 2024-12-20 09:05:15 字数 64 浏览 2 评论 0原文

我记得很久以前用 OpenSSL 做过这个,但我想知道它是否可能以及如何实现,我从未在 java 上使用过密码学。

I remember do this long time ago with OpenSSL, but I want to know if it's possible and how, I've never used Cryptography on java.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑色毁心梦 2024-12-27 09:05:15

假设我们正在谈论 RSA 私钥和公钥。然后,如果您使用 PEM 格式文件,那么首先需要将文件中的私钥读取到 PrivateKey 对象中:

    public PrivateKey readPemRsaPrivateKey(String pemFilename) throws
            java.io.IOException,
            java.security.NoSuchAlgorithmException,
            java.security.spec.InvalidKeySpecException
    {
            String pemString = File2String(pemFilename);

            pemString = pemString.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
            pemString = pemString.replace("-----END RSA PRIVATE KEY-----", "");

            byte[] decoded = Base64.decodeBase64(pemString);

            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory kf = KeyFactory.getInstance("RSA");

            return kf.generatePrivate(keySpec);
    }

其中 File2String 类似于:

    private static String File2String(String fileName) throws
            java.io.FileNotFoundException, java.io.IOException
    {
            File file = new File(fileName);

            char[] buffer = null;

            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

            buffer = new char[(int)file.length()];

            int i = 0;
            int c = bufferedReader.read();

            while (c != -1) {
                    buffer[i++] = (char)c;
                    c = bufferedReader.read();
            }
            return new String(buffer);
    }

现在您可以使用如下代码生成相应的 PublicKey:

    import java.security.interfaces.RSAPrivateCrtKey;
    import java.security.spec.RSAPublicKeySpec;

...

    PrivateKey myPrivateKey = readPemRsaPrivateKey(myPrivateKeyPemFileName);
    RSAPrivateCrtKey privk = (RSAPrivateCrtKey)myPrivateKey;

    RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey myPublicKey = keyFactory.generatePublic(publicKeySpec);

学分:如何通过提供 RSA 公钥私钥?

The assumption is that we are talking about RSA private and Public keys. Then, if you are working from a PEM format file, then first you need to read the private key from the file into a PrivateKey object:

    public PrivateKey readPemRsaPrivateKey(String pemFilename) throws
            java.io.IOException,
            java.security.NoSuchAlgorithmException,
            java.security.spec.InvalidKeySpecException
    {
            String pemString = File2String(pemFilename);

            pemString = pemString.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
            pemString = pemString.replace("-----END RSA PRIVATE KEY-----", "");

            byte[] decoded = Base64.decodeBase64(pemString);

            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory kf = KeyFactory.getInstance("RSA");

            return kf.generatePrivate(keySpec);
    }

where File2String is something like:

    private static String File2String(String fileName) throws
            java.io.FileNotFoundException, java.io.IOException
    {
            File file = new File(fileName);

            char[] buffer = null;

            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

            buffer = new char[(int)file.length()];

            int i = 0;
            int c = bufferedReader.read();

            while (c != -1) {
                    buffer[i++] = (char)c;
                    c = bufferedReader.read();
            }
            return new String(buffer);
    }

Now you can generate the corresponding PublicKey with code like this:

    import java.security.interfaces.RSAPrivateCrtKey;
    import java.security.spec.RSAPublicKeySpec;

...

    PrivateKey myPrivateKey = readPemRsaPrivateKey(myPrivateKeyPemFileName);
    RSAPrivateCrtKey privk = (RSAPrivateCrtKey)myPrivateKey;

    RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey myPublicKey = keyFactory.generatePublic(publicKeySpec);

Credits: How to get a RSA PublicKey by giving a PrivateKey?

原来是傀儡 2024-12-27 09:05:15

请确保Eli Rosencruft的答案基本正确,但模数和公共指数的顺序不正确!这是正确的说法:

RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());

Please make sure that Eli Rosencruft answer is basically correct, but the order of the modulus and the public exponent are incorrect! This is the correct statement:

RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());
楠木可依 2024-12-27 09:05:15

您不能直接从另一个密钥生成另一个密钥。这在数学上是不可能的。如果您有一个包含公钥和私钥的密钥 blob,则可以相对轻松地提取其中任何一个。

编辑,2017:很多年了,后来对加密有了更好的理解,现在我很清楚这个答案并不正确。

引用维基百科:

公钥由模数 n 和公共(或加密)指数 e 组成。私钥由模数 n 和私有(或解密)指数 d 组成,必须保密。 p、q 和 λ(n) 也必须保密,因为它们可以用来计算 d。

公共模数 n 可以计算为 p × q。原始私钥中唯一缺少的是 e,但该值通常选择为 65537,如果没有,您仍然可以根据 d 和 λ(n) 计算 e。

然而,许多私钥存储格式实际上包含公共模数 n 以及其他组件,因此您可以直接提取值。

编辑,2018:仍然对此投反对票,这是正确的!我留下这个答案是为了让人们知道我最初为什么错了,并提醒自己以后不要再犯错。

You cannot generate either key directly from the other. It is mathematically impossible. If you had a key blob that contained both the public and private keys, you could extract either one of them with relative ease.

EDIT, 2017: Many years and a much better understanding of crypto later, and it's now clear to me that this answer isn't really correct.

To quote Wikipedia:

The public key consists of the modulus n and the public (or encryption) exponent e. The private key consists of the modulus n and the private (or decryption) exponent d, which must be kept secret. p, q, and λ(n) must also be kept secret because they can be used to calculate d.

The public modulus n can be computed as p × q. The only thing missing from a raw private key is e, but this value is usually selected as 65537, and if not you can still compute e from d and λ(n).

However, many private key storage formats actually contain the public modulus n alongside the other components, so you can just do a direct extraction of the values.

EDIT, 2018: Still getting downvotes for this, and rightly so! I'm leaving this answer up so people can see why I was originally wrong, and to remind myself not to be wrong in future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文