Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java-如何从密钥库(.p12)开始生成PrivateKey和PublicKey_Java_Private Key_Pkcs#12_Pkcs#8 - Fatal编程技术网

java-如何从密钥库(.p12)开始生成PrivateKey和PublicKey

java-如何从密钥库(.p12)开始生成PrivateKey和PublicKey,java,private-key,pkcs#12,pkcs#8,Java,Private Key,Pkcs#12,Pkcs#8,使用OpenSSL生成一些密钥,然后在Base64中对它们进行编码并获取它们,然后尝试生成它们以使用JWT验证身份验证。下面是发生在我身上的事情的代码和描述 使用以下命令生成: openssl req -x509 -newkey rsa:4096 -keyout private_key.pem -out public_key.der openssl pkcs12 -export -out keyStore.p12 -inkey private_key.pem -in public_ke

使用OpenSSL生成一些密钥,然后在Base64中对它们进行编码并获取它们,然后尝试生成它们以使用JWT验证身份验证。下面是发生在我身上的事情的代码和描述 使用以下命令生成:

  openssl req -x509 -newkey rsa:4096 -keyout private_key.pem -out public_key.der

  openssl pkcs12 -export -out keyStore.p12 -inkey private_key.pem -in public_key.der

  base64 –w 0 private_key.pem > private_key_base64_enc.txt 

  base64 –w 0 public_key.der > public_key_base64_enc.txt
我保存在wildfly的vault.keystore中:private_key_base64_enc.txt和public_key_base64_enc.txt

然后在我的java类中编写以下代码:

 private void jwtSignedAuthentication(String token, PropName vaultBlockName) throws Exception
    {


        String rsa512Alias = vaultBlockName.getDefaultValue();

        String rsa512pvt = VaultReader.getValue(rsa512Alias, "privateKey");
        String rsa512pbc = VaultReader.getValue(rsa512Alias, "publicKey");

        KeyFactory keyfatc = null;
        PrivateKey privateKey = null;
        PublicKey publicKey = null;

        try {
            keyfatc = KeyFactory.getInstance("RSA");

        } catch (NoSuchAlgorithmException e) {
             logger.error(e);
        }


        StringBuilder pkcs8Lines = new StringBuilder();
        BufferedReader rdr = new BufferedReader(new StringReader(new String(Base64.getDecoder().decode(rsa512pvt.getBytes()))));

        String line;
        while ((line = rdr.readLine()) != null) {
            pkcs8Lines.append(line);
        }

        // Remove the "BEGIN" and "END" lines, as well as any whitespace

        String pkcs8Pem = pkcs8Lines.toString();
        pkcs8Pem = pkcs8Pem.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "");
        pkcs8Pem = pkcs8Pem.replace("-----END ENCRYPTED PRIVATE KEY-----", "");
        pkcs8Pem = pkcs8Pem.replaceAll("\\s+","");

        byte[] dataPvt = Base64.getDecoder().decode(pkcs8Pem.getBytes());
        PKCS8EncodedKeySpec specPvt = new PKCS8EncodedKeySpec(dataPvt);

        byte[] dataPbc = Base64.getDecoder().decode(rsa512pbc.getBytes());

        StringBuilder publicLinesBuilder = new StringBuilder();
        BufferedReader readerPlubKey = new BufferedReader(new StringReader(new String(dataPbc)));

        String lineP;
        while ((lineP = readerPlubKey.readLine()) != null) {
            publicLinesBuilder.append(lineP);
        }


        String pubK = publicLinesBuilder.toString();
        pubK = pubK.replace("-----BEGIN CERTIFICATE-----", "");
        pubK = pubK.replace("-----END CERTIFICATE-----", "");
        pubK = pubK.replaceAll("\\s+","");
        X509EncodedKeySpec specPbc = new X509EncodedKeySpec(Base64.getDecoder().decode(pubK.getBytes()));

        try {

            privateKey = keyfatc.generatePrivate(specPvt);
            publicKey = keyfatc.generatePublic(specPbc);

        } catch (InvalidKeySpecException e) {
            logger.error(e);

        }

        Algorithm algorithm = Algorithm.RSA512((RSAPublicKey) publicKey, (RSAPrivateKey) privateKey);

        // Creación de un verificador JWT
        JWTVerifier verifier = JWT.require(algorithm).withIssuer(JWT_CLAIM_ISSUER).acceptLeeway(2).build();

        UserContext userContext = new UserContext();
        userContext.setUserName(JWT_CLAIM_ISSUER);

        try {
            // Decode JWT, verificación del token.
            @SuppressWarnings("unused")
            DecodedJWT decodeJwt = verifier.verify(token);

        } catch (JWTDecodeException e) {
        logger.error(e);
        }

    }
当我尝试生成密钥时,我返回null:

privateKey = keyfatc.generatePrivate(specPvt);
publicKey = keyfatc.generatePublic(specPbc);
任何人都知道这会发生什么。提前谢谢

对于生成我的JWT:

 public ResteasyWebTarget getClientWebAgent(String host, String blockName) throws KeyStoreException
    {
        ResteasyClient clientBuilder = new ResteasyClientBuilder().establishConnectionTimeout(10, TimeUnit.SECONDS).socketTimeout(5, TimeUnit.SECONDS).build();
        ResteasyWebTarget target = clientBuilder.target(host);
        KeyPair keys = null;
        try {
            keys = keyStore.getKeys();
            /*logger.infov(new String(Base64.getEncoder().encode(keys.getPrivate().getEncoded())));
            logger.infov("****PUBLIC KEY ******");
            logger.infov(new String(keys.getPublic().getEncoded()));*/
        } catch (IOException e) {
            logger.error(e);
        }
          Algorithm algorithm = Algorithm.RSA512((RSAPublicKey) keys.getPublic(), (RSAPrivateKey) keys.getPrivate());
          Map<String, Object> headerClaims = new HashMap<>();
          headerClaims.put("alg", "RS512");
          headerClaims.put("typ", "JWT");

          JWTCreator.Builder jwtCreator = JWT.create();
          jwtCreator.withHeader(headerClaims);
          jwtCreator.withIssuer(JWT_CLAIM_ISSUER);
          jwtCreator.withIssuedAt(LocalDate.now().toDate());
          jwtCreator.withExpiresAt(LocalDate.now().toDateTimeAtCurrentTime().plusSeconds(30).toDate());
          String jwtToken = jwtCreator.sign(algorithm);
          target.register(new BearerAuthenticator(jwtToken));
          target.register(new LanguageHeaderToken(Locale.getDefault()));

        return target;
    }

可能您在生成密钥库时没有指定有效的别名,查看您的命令时没有使用-name选项。 命令应如下所示:

openssl pkcs12 -export -out keyStore.p12 -inkey private_key.pem -in public_key.der -name "alias"  
在java中使用密钥的更智能的方法是创建密钥对:

然后从密钥对中提取RSAPPublicKey和RSAPPrivateKey密钥:

void loadKeys() throws Exception{
    KeyPair keyPair = loadKeyPair();

    if (null != keyPair) {
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
    }
}

希望它能对您的Json Web令牌有所帮助并祝您好运!:-p

可能您在生成密钥库时没有指定有效的别名,查看您的命令时没有使用-name选项。 命令应如下所示:

openssl pkcs12 -export -out keyStore.p12 -inkey private_key.pem -in public_key.der -name "alias"  
在java中使用密钥的更智能的方法是创建密钥对:

然后从密钥对中提取RSAPPublicKey和RSAPPrivateKey密钥:

void loadKeys() throws Exception{
    KeyPair keyPair = loadKeyPair();

    if (null != keyPair) {
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
    }
}

希望它能对您的Json Web令牌有所帮助并祝您好运!:-p

您的“公钥”实际上是一个证书,具体是一个X.509 v1或v3证书,具体取决于您的openssl配置,它包含一个公钥,但与公钥不同-并且是PEM格式的,即使您错误地将其命名为.der-并且您的私钥是加密的

除了使用PKCS12的方法外,正如Roberto有效地建议的那样,它通常是最简单的,因为它只需要管理一个文件,而且仍然是加密的,因此更安全:

Java可以处理X.509证书,但您可以使用CertificateFactory.getInstanceX.509并为其提供InputStream,而不是KeyFactory和X509EncodedKeySpec。CertificateFactory可以处理PEM或DER,不像KeyFactory只能处理DER,因此您不需要de PEM条带BEGIN/END/EOL和decode base64部件

标准Java无法直接处理加密的PKCS8密钥。如果您可以添加第三方库,BouncyCastle的bcpkix可以这样做;搜索十几个使用PEMParser而不是PEMReader的现有Qs,这是较早的版本和JceOpenSSLPKCS8DecryptorBuilder。否则,您可以将-nodes添加到req-newkey-x509命令中,以生成未加密的privatekey文件,在取消PEM后,该文件在带有PKCS8EncodedKeySpec的KeyFactory中工作。它仍然是拼写节点,即使在没有它的情况下使用的加密几十年来都不是简单的单DES。使用未加密的私钥文件当然意味着系统中任何可以读取该文件的入侵者或恶意软件都可以获取私钥,这在许多情况下都是一种风险

最后,如果您真的只需要密钥对,而不需要证书,那么就不用麻烦使用req-newkey-x509。而是使用openssl genpkey生成私钥,或者使用更老但更简单的openssl genrsa-节点,后跟或通过管道连接到openssl pkcs8-topk8-nocrypt以将其转换为pkcs8未加密格式。然后使用openssl pkey-pubout或较旧的openssl rsa-pubout使用公钥创建一个单独的文件。这些命令可以在适用的情况下写入和读取DER格式,而不是PEM格式;如果这样做,代码就不需要de-PEM步骤,只需将二进制文件内容传递给KeyFactory即可。未加密文件的风险与上述相同


您的“公钥”实际上是一个证书,特别是一个X.509 v1或v3证书,具体取决于您的openssl配置,它包含一个公钥,但与公钥不同-并且是PEM格式的,即使您错误地将其命名为.der-并且您的私钥是加密的

除了使用PKCS12的方法外,正如Roberto有效地建议的那样,它通常是最简单的,因为它只需要管理一个文件,而且仍然是加密的,因此更安全:

Java可以处理X.509证书,但您可以使用CertificateFactory.getInstanceX.509并为其提供InputStream,而不是KeyFactory和X509EncodedKeySpec。CertificateFactory可以处理PEM或DER,不像KeyFactory只能处理DER,因此您不需要de PEM条带BEGIN/END/EOL和decode base64部件

标准Java无法直接处理加密的PKCS8密钥。如果您可以添加第三方库,BouncyCastle的bcpkix可以这样做;搜索十几个使用PEMParser而不是PEMReader的现有Qs,这是较早的版本和JceOpenSSLPKCS8DecryptorBuilder。否则,您可以将-nodes添加到req-newkey-x509命令中,以生成未加密的privatekey文件,在取消PEM后,该文件在带有PKCS8EncodedKeySpec的KeyFactory中工作。它仍然是拼写节点,即使e 几十年来,不使用它的加密技术都不是简单的单一DES。使用未加密的私钥文件当然意味着系统中任何可以读取该文件的入侵者或恶意软件都可以获取私钥,这在许多情况下都是一种风险

最后,如果您真的只需要密钥对,而不需要证书,那么就不用麻烦使用req-newkey-x509。而是使用openssl genpkey生成私钥,或者使用更老但更简单的openssl genrsa-节点,后跟或通过管道连接到openssl pkcs8-topk8-nocrypt以将其转换为pkcs8未加密格式。然后使用openssl pkey-pubout或较旧的openssl rsa-pubout使用公钥创建一个单独的文件。这些命令可以在适用的情况下写入和读取DER格式,而不是PEM格式;如果这样做,代码就不需要de-PEM步骤,只需将二进制文件内容传递给KeyFactory即可。未加密文件的风险与上述相同


我使用密钥对在JWT中生成算法,明天我将分享代码,但这部分我认为还可以。谢谢,@Roberto ManfredaI使用KeyPair在JWT中生成算法,明天我将分享代码,但我认为这部分很好。谢谢,@Roberto ManfredaJust将.p12加载到PKCS12类型的密钥库中并使用API。不需要所有这些。只需将.p12加载到PKCS12类型的密钥库中并使用API即可。不需要这些。