简体   繁体   English

如何将 Curl SSL 请求转换为 Java 代码

[英]How to convert Curl SSL requests into Java code

Curl allows making 2-way SSL requests by specifying the certificate and private key files like the two curl requests below Curl 允许通过指定证书和私钥文件(如下面的两个 curl 请求)来发出 2 路 SSL 请求

  1. First get an access token:首先获取访问令牌:

    $ curl https://connect2.server.com/auth/token $ curl https://connect2.server.com/auth/token
    -H "Authorization: Basic $BASIC_AUTH" -H "授权:基本 $BASIC_AUTH"
    --cert ~/certs/certpath/fullchain.pem --cert ~/certs/certpath/fullchain.pem
    --key ~/certs/certpath/privkey.pem --key ~/certs/certpath/privkey.pem

  2. Then use the token to access the API:然后使用令牌访问API:

    $ curl https://connect2.server.com/api/public/preview1/orgs/$ORGUUID/API $ curl https://connect2.server.com/api/public/preview1/orgs/$ORGUUID/API
    -H "Authorization: Bearer $ACCESS_TOKEN" -H "授权:持有者 $ACCESS_TOKEN"
    --cert ~/certs/certpath/fullchain.pem --cert ~/certs/certpath/fullchain.pem
    --key ~/certs/certpath/privkey.pem --key ~/certs/certpath/privkey.pem

Question:问题:

How to implement the above requests in Java? Java中的上述请求如何实现? What libraries are required?需要哪些库? Java seems to use p12 file, however, we have.pem files. Java 好像用的是 p12 文件,但是我们有.pem 文件。

1. You can convert PEM privatekey plus chain to a PKCS12 file using openssl pkcs12 -export . 1. 您可以使用openssl pkcs12 -export将 PEM 私钥加链转换为 PKCS12 文件。 That is not programming or development and no longer ontopic here, but there are dozens of Qs about this here going back many years when topicality was broader, as well as in other Stacks (security.SX, serverfault, superuser, maybe more).这不是编程或开发,也不再是这里的主题,但是这里有几十个关于这个的问题可以追溯到很多年前,当主题更广泛时,以及其他堆栈(security.SX、serverfault、超级用户,也许更多)。

2. If you don't have or dislike OpenSSL, you can read those files (among others) into any kind of Java keystore (JCEKS, JKS, PKCS12, and several BouncyCastle variants you probably don't want) using the software from https://www.keystore-explorer.org . 2. If you don't have or dislike OpenSSL, you can read those files (among others) into any kind of Java keystore (JCEKS, JKS, PKCS12, and several BouncyCastle variants you probably don't want) using the software from https ://www.keystore-explorer.org That's also offtopic, and I've seen some existing Qs mention it but not many.这也是题外话,我已经看到一些现有的 Q 提到它,但并不多。

3. If you want to do this with your own code, which is ontopic, and assuming your curl uses OpenSSL or at least those files are OpenSSL formats: 3. 如果你想用你自己的代码来做这个,这ontopic,假设你的 curl 使用 OpenSSL 或至少这些文件是 OpenSSL 格式:

3.0 Java can read PEM cert sequence with CertificateFactory.getInstance("X.509") then generateCertificates(InputStream) (note s) -- the doc is a bit sketchy but this method actually can handle separate certs as DER or PEM (which you apparently have), or PKCS7 containing certs as a single blob (commonly called p7b or p7c) ditto. 3.0 Java 可以使用CertificateFactory.getInstance("X.509")然后generateCertificates(InputStream)读取 PEM 证书序列(注释 s)——文档有点粗略,但这种方法实际上可以处理单独的证书作为 DERPEM(你显然有),或 PKCS7 包含证书作为单个 blob(通常称为 p7b 或 p7c)同上。

3.1 if that privkey file is PKCS8-unencrypted, ie if the PEM labels are BEGIN/END PRIVATE KEY with no other word between, that case can be handled by standard Java, assuming you know what algorithm it is for (which if necessary you can determine from the first=leaf certificate). 3.1如果该私钥文件是 PKCS8 未加密的,即如果 PEM 标签是BEGIN/END PRIVATE KEY之间没有其他词,则该情况可以由标准 Java 处理,假设您知道它是什么算法(如果需要,您可以从第一个=叶证书确定)。 Delete the BEGIN/END lines and decode the rest from base64 to binary either ignoring linebreaks (with Base64.getMimeDecoder() ) or with .getDecoder() after deleting the linebreaks.删除 BEGIN/END 行并将 rest 从 base64 解码为二进制,忽略换行符(使用Base64.getMimeDecoder() ) 或删除换行符后使用.getDecoder() Put the result in PKCS8EncodedKeySpec and feed it to generatePrivate in a KeyFactory instance for the correct algorithm.将结果放入PKCS8EncodedKeySpec并将其提供给KeyFactory实例中的generatePrivate以获取正确的算法。

3.2 BouncyCastle (bcpkix+bcprov) can read all the PEM formats for privatekey used by OpenSSL with PEMParser and JcaPEMKeyConverter and if applicable a DecryptorBuilder . 3.2 BouncyCastle (bcpkix+bcprov) 可以读取 OpenSSL 使用PEMParserJcaPEMKeyConverter以及DecryptorBuilder所有PEM 格式。 There are many existing Qs on this that you can find with that fairly-unique classname.您可以使用该相当独特的类名找到许多现有的 Q。 This does mean a dependency on Bouncy.这确实意味着对 Bouncy 的依赖。

3.3 if you don't have or don't want Bouncy and have a format other than PKCS8-unencrypted, life gets harder. 3.3 如果您没有或不想要 Bouncy 并且拥有除 PKCS8 未加密的格式,那么生活会变得更加艰难。 You could avoid this by using OpenSSL to convert the privkey file to PKCS8-unencrypted putting you back in #3.1, but if you do that you might as well go way back to #1 and use OpenSSL to convert the lot to PKCS12 in one foop. You could avoid this by using OpenSSL to convert the privkey file to PKCS8-unencrypted putting you back in #3.1, but if you do that you might as well go way back to #1 and use OpenSSL to convert the lot to PKCS12 in one foop .

  • if you have an OpenSSL 'traditional' algorithm-specific format like BEGIN/END RSA PRIVATE KEY or BEGIN/END EC PRIVATE KEY , and the first two lines after BEGIN are NOT Proc-type: 4 and DEK-info, you can base64-decode the body and convert it to PKCS8 by adding a (DER) prefix in front that specifies the algorithm and 'wraps' the algorithm-specific part.如果您有 OpenSSL '传统'算法特定格式,例如BEGIN/END RSA PRIVATE KEYBEGIN/END EC PRIVATE KEY ,并且 BEGIN 之后的前两行不是 Proc-type: 4 和 DEK-info,您可以使用 base64-解码正文并将其转换为 PKCS8,方法是在前面添加一个 (DER) 前缀,指定算法并“包装”特定于算法的部分。 I think there are dupes for this but I can't presently find any;认为这有骗局,但我目前找不到; if this case applies and you identify the algorithm I'll add it.如果这种情况适用并且您确定了我将添加的算法。

  • if you have a 'traditional' format that does have Proc-type: 4 and DEK-info, or you have BEGIN/END ENCRYPTED PRIVATE KEY , those are encrypted.如果你有一个“传统”格式,它确实有 Proc-type: 4 和 DEK-info,或者你有BEGIN/END ENCRYPTED PRIVATE KEY ,这些都是加密的。 Making sense of them with only standard Java is a fair bit of work which I'll do only if you can't use the other options and specify exactly what case you have.仅使用标准 Java 来理解它们是一项相当大的工作,只有当您无法使用其他选项并准确指定您拥有的情况时,我才会这样做。

Following are the steps & code to add SSL certificates into HTTP Post request.以下是将 SSL 证书添加到 HTTP 发布请求中的步骤和代码。

STEP 1. CONVERT PEM CERTIFICATE TO P12 FORMAT步骤 1. 将 PEM 证书转换为 P12 格式

openssl pkcs12 -export -out cacert.p12 -inkey /etc/letsencrypt/archive/server/privkey21.pem -in /etc/letsencrypt/archive/server/cert21.pem -certfile /etc/letsencrypt/archive/server/chain21.pem -passin pass:PWD -passout pass:PWD

STEP 2. (OPTIONAL NOT REQUIRED) CONVERT CERTIFICATE P12 TO JKS FORMAT第 2 步。(可选,不需要)将证书 P12 转换为 JKS 格式

keytool -importkeystore -srckeystore cacert.p12 -srcstoretype pkcs12 -destkeystore cacert.jks

STEP 3. ADD CERTIFICATE TO HTTP POST REQUEST THROUGH SSLSocketFactory步骤 3. 通过 SSLSocketFactory 向 HTTP POST 请求添加证书

/**
* This function is responsible to create createSSLSocketFactory with SSL certificate
* @return
*/
public static SSLSocketFactory createSSLSocketFactory(){
      try 
      {
             FileInputStream f5 = new FileInputStream(new File("/etc/letsencrypt/archive/server/cacert21.p12"));
             KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
             KeyStore ks1 = KeyStore.getInstance(KeyStore.getDefaultType());
             ks1.load(f5, "PWD".toCharArray());
             kmf.init(ks1, "PWD".toCharArray());
             
             SSLContext sslContext = SSLContext.getInstance("SSL");
             sslContext.init(kmf.getKeyManagers(), null, null);
             
             f5.close();
             return sslContext.getSocketFactory();
      }
      catch (Exception e) {
             e.printStackTrace();
             return null;
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM