Java 从AWS凭据提供程序获取安全令牌

Java 从AWS凭据提供程序获取安全令牌,java,amazon-web-services,primary-key,aws-iot,x509securitytokenmanager,Java,Amazon Web Services,Primary Key,Aws Iot,X509securitytokenmanager,有人能给我解释一下,我需要如何从这开始实施第一步吗? 我在AWS文档中找不到它 换句话说,我需要翻译一个命令: curl --cert eeb81a0eb6-certificate.pem.crt --key eeb81a0eb6-private.pem.key -H "x-amzn-iot-thingname: myThingName" --cacert AmazonRootCA1.pem https://<prefix>.credentials.iot.us-

有人能给我解释一下,我需要如何从这开始实施第一步吗? 我在AWS文档中找不到它

换句话说,我需要翻译一个命令:

curl --cert eeb81a0eb6-certificate.pem.crt --key eeb81a0eb6-private.pem.key -H "x-amzn-iot-thingname: myThingName" --cacert AmazonRootCA1.pem https://<prefix>.credentials.iot.us-west-2.amazonaws.com/role-aliases/MyAlias/credentials
另一个更新(我已经尝试过了)

  • 将myPrivateKey和deviceCertificate转换为JKS:

    winpty openssl pkcs12-导出-在eeb81a0eb6-certificate.pem.crt中-inkey eeb81a0eb6-private.pem.key-名称mycompany.com-out my.p12

    keytool-importkeystore-destkeystore mycompany.jks-srckeystore my.p12-srcstoretypkcs12

  • 使用我的代码中的JKS:

     System.setProperty("deployment.security.TLSv1.2", "true");
     System.setProperty("https.protocols", "TLSv1.2");
     System.setProperty("javax.net.debug", "ssl");
    
     HttpPost request = new HttpPost(clientEndpoint);
     request.setHeader("x-amzn-iot-thingname", "0ad16050-d974-4f78-88ea-c6ee2b0a551e");
    
     KeyStore keyStore;
     try (InputStream keyStoreStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) {
         keyStore = KeyStore.getInstance("PKCS12");
         keyStore.load(keyStoreStream, KEYSTOREPASS.toCharArray());
     }
    
     SSLContext sslContext = SSLContexts.custom()
             .loadKeyMaterial(keyStore, KEYPASS.toCharArray()) // use null as second param if you don't have a separate key password
             .loadTrustMaterial(null, new TrustSelfSignedStrategy())
             .build();   
    
     SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
     Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                                                     .register("https", sslConnectionSocketFactory)
                                                     .register("http", new PlainConnectionSocketFactory())
                                                     .build();
    
     BasicHttpClientConnectionManager manager = new BasicHttpClientConnectionManager(registry);
    
     try (CloseableHttpClient httpClient = HttpClients
                                             .custom()
                                             .setSSLSocketFactory(sslConnectionSocketFactory)
                                             .setConnectionManager(manager)
                                             .build();
          CloseableHttpResponse response = httpClient.execute(request)) {
    
    
         System.out.println();
    
    
    
     } catch (IOException e) {
         System.err.println(e);
     }
    
    System.setProperty(“deployment.security.TLSv1.2”、“true”);
    System.setProperty(“https.protocols”、“TLSv1.2”);
    setProperty(“javax.net.debug”、“ssl”);
    HttpPost请求=新的HttpPost(客户端端点);
    请求。setHeader(“x-amzn-iot-thingname”、“0ad16050-d974-4f78-88ea-c6ee2b0a551e”);
    密钥库;
    try(InputStream keystrestream=this.getClass().getResourceAsStream(KEYSTOREPATH)){
    keyStore=keyStore.getInstance(“PKCS12”);
    load(keystoream,keystrepass.toCharArray());
    }
    SSLContext SSLContext=SSLContexts.custom()
    .loadKeyMaterial(keyStore,KEYPASS.toCharArray())//如果没有单独的密钥密码,请使用null作为第二个参数
    .loadTrustMaterial(空,新TrustSelfSignedStrategy())
    .build();
    SSLConnectionSocketFactory SSLConnectionSocketFactory=新的SSLConnectionSocketFactory(sslContext);
    Registry Registry=RegistryBuilder.create()
    .register(“https”,sslConnectionSocketFactory)
    .register(“http”,新的PlainConnectionSocketFactory())
    .build();
    BasicHttpClientConnectionManager=新的BasicHttpClientConnectionManager(注册表);
    try(CloseableHttpClient-httpClient=HttpClients
    .custom()
    .setSSLSocketFactory(sslConnectionSocketFactory)
    .setConnectionManager(管理器)
    .build();
    CloseableHttpResponse response=httpClient.execute(请求)){
    System.out.println();
    }捕获(IOE异常){
    系统错误println(e);
    }
    
  • 我得到一个例外:

    javax.net.ssl.SSLHandshakeException:收到致命警报:错误的\u证书


  • AWS SDK提供了多种实现,您可以使用这些实现与Amazon服务进行同步或异步交互

    例如,您可以使用该类

    所有这些HTTP客户端都是使用s创建和配置的,用于
    ApacheHttpClient

    ApacheHttpClient.Builder
    提供了一些方法,允许您为客户端、远程对等或相互身份验证配置安全的HTTP连接

    如果必须对客户端进行身份验证,则必须提供用于此目的的证书和私钥,对应于
    curl
    调用的
    --cert
    --key
    参数

    通常,此证书和私钥存储在一个受密码保护的
    密钥库中,通常采用PKCS#12格式(一个
    .p12
    .pfx
    文件)

    此信息可通过两种方式访问
    ApacheHttpClient.Builder

    首先,通过设置一系列
    系统
    属性:

    import static software.amazon.awssdk.utils.JavaSystemSetting.SSL\u KEY\u STORE;
    导入static software.amazon.awssdk.utils.JavaSystemSetting.SSL\u KEY\u STORE\u PASSWORD;
    导入static software.amazon.awssdk.utils.JavaSystemSetting.SSL\u KEY\u STORE\u TYPE;
    //...
    Path clientKeyStore=Path.get(…);
    System.setProperty(SSL_KEY_STORE.property(),clientKeyStore.toabsolutionPath().toString());
    System.setProperty(SSL_KEY_STORE_TYPE.property(),“pkcs12”);
    System.setProperty(SSL_KEY_STORE_PASSWORD.property(),“PASSWORD”);
    
    注意:
    static
    导入仅是标准属性
    javax.net.ssl.keyStore
    javax.net.ssl.keystrepassword
    javax.net.ssl.keyStoreType
    的常量

    其次,通过为
    ApacheHttpClient.Builder
    tlsKeyManagersProvider
    方法提供实现。例如:

    Path clientKeyStore=。。。
    TlsKeyManagersProvider keyManagersProvider=filestoreskeymanagersprovider.create(clientKeyStore,“pkcs12”,“password”);
    
    事实上,上述基于属性的
    系统配置由另一个
    TlsKeyManagersProvider
    实现使用

    如果需要对服务器进行身份验证,您还有两个选项

    首先,再次设置几个
    系统
    属性:

    Path-serverKeyStore=Path.get(…);
    setProperty(“javax.net.ssl.trustStore”,serverKeyStore.toabsolutionPath().toString());
    setProperty(“javax.net.ssl.trustStorePassword”、“password”);
    setProperty(“javax.net.ssl.trustStoreType”、“jks”);
    
    如您所见,为了简单起见,这次我们使用了一种不同的
    密钥库
    jks
    。您可以从AWS服务器证书PEM文件(与
    curl
    命令中的
    --cacert
    相关联的文件)构建这样一个
    密钥库,如下所示:

    路径路径=。。。; try(最终输入流为=Files.newInputStream(pemPath){ CertificateFactory CertificateFactory=CertificateFactory.getInstance(“X.509”); X509Certificate cert=(X509Certificate)certificateFactory.generateCertificate(is); 字符串别名=cert.getSubjectX500Principal().getName(); KeyStore KeyStore=KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); keyStore.setCertificateEntry(别名,ce
     System.setProperty("deployment.security.TLSv1.2", "true");
     System.setProperty("https.protocols", "TLSv1.2");
     System.setProperty("javax.net.debug", "ssl");
    
     HttpPost request = new HttpPost(clientEndpoint);
     request.setHeader("x-amzn-iot-thingname", "0ad16050-d974-4f78-88ea-c6ee2b0a551e");
    
     KeyStore keyStore;
     try (InputStream keyStoreStream = this.getClass().getResourceAsStream(KEYSTOREPATH)) {
         keyStore = KeyStore.getInstance("PKCS12");
         keyStore.load(keyStoreStream, KEYSTOREPASS.toCharArray());
     }
    
     SSLContext sslContext = SSLContexts.custom()
             .loadKeyMaterial(keyStore, KEYPASS.toCharArray()) // use null as second param if you don't have a separate key password
             .loadTrustMaterial(null, new TrustSelfSignedStrategy())
             .build();   
    
     SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
     Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                                                     .register("https", sslConnectionSocketFactory)
                                                     .register("http", new PlainConnectionSocketFactory())
                                                     .build();
    
     BasicHttpClientConnectionManager manager = new BasicHttpClientConnectionManager(registry);
    
     try (CloseableHttpClient httpClient = HttpClients
                                             .custom()
                                             .setSSLSocketFactory(sslConnectionSocketFactory)
                                             .setConnectionManager(manager)
                                             .build();
          CloseableHttpResponse response = httpClient.execute(request)) {
    
    
         System.out.println();
    
    
    
     } catch (IOException e) {
         System.err.println(e);
     }