java - Azure key 保管库。无法使用相同的 key 和算法解密返回的值

标签 java azure encryption

我有一个简单的 java 程序,它使用 Azure KeyVault 加密一些明文,然后解密。

但是解密总是失败

{"error":{"code":"BadParameter","message":"Request body not specified"}}

这是java测试类

package uk.co.his.azure.keyvault.test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import us.monoid.json.JSONException;
import us.monoid.json.JSONObject;

import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import com.microsoft.aad.adal4j.ClientCredential;

public class CopyOfTestClientLogon {

    public final static String AAD_HOST_NAME = "login.windows.net";
    public final static String AAD_TENANT_NAME = "From Azure portal ActiveDirectory app page endpoints";
    public final static String AAD_TENANT_ENDPOINT = "https://" + AAD_HOST_NAME
            + "/" + AAD_TENANT_NAME + "/";
    public final static String AAD_CLIENT_ID = "From Azure portal ActiveDirectory app page";
    public final static String AAD_CLIENT_SECRET = "Copied From Portal";
    public final static String KEY_NAME = "TestKey1";
    private static final ContentType JsonContentType = ContentType.parse("application/json");
    private static final String KEY_ENCRYPT_ALG = "RSA1_5";


    @Test
    public void testEncryptWithKey() throws InterruptedException, ExecutionException, JSONException, URISyntaxException, ClientProtocolException, IOException
    {
        AuthenticationContext ctx = new AuthenticationContext(AAD_TENANT_ENDPOINT, true, Executors.newFixedThreadPool(1));
        Future<AuthenticationResult> resp = ctx.acquireToken("https://vault.azure.net", new ClientCredential(AAD_CLIENT_ID, AAD_CLIENT_SECRET), null);
        AuthenticationResult res = resp.get();


        String plainText = "This is a test";
        String plainTextB64Encoded = Base64.encodeBase64URLSafeString(plainText.getBytes("UTF-8"));
        JSONObject req = new JSONObject();
        req.put("alg", KEY_ENCRYPT_ALG);
        req.put("value", plainTextB64Encoded);
        byte[] payload = req.toString().getBytes("UTF-8");

        ByteArrayInputStream message = new ByteArrayInputStream(req.toString().getBytes("UTF-8"));

        InputStreamEntity reqEntity = new InputStreamEntity(message, payload.length, JsonContentType);
        reqEntity.setChunked(true);

        URIBuilder ub = new URIBuilder(
                "https://aexpress-dev1-key-vault.vault.azure.net/keys/"+KEY_NAME+"/encrypt?api-version=2014-12-08-preview");
        URI uri = ub.build();
        HttpUriRequest request = RequestBuilder.post().setUri(uri)
                .setHeader(HttpHeaders.AUTHORIZATION, "Bearer "+res.getAccessToken())
                .setEntity(reqEntity).build();
        HttpClient client = HttpClientBuilder.create().build(); // TODO server
                                                                // cert
                                                                // authentication
        HttpResponse response = client.execute(request);
        int status = response.getStatusLine().getStatusCode();
        HttpEntity entity = response.getEntity();
        String body = null;
        if(entity==null) {
            System.err.println("No body");
            throw new ClientProtocolException("Response has no body");
        }
        else {
            body = EntityUtils.toString(entity);
        }
        JSONObject reply = new JSONObject(body);
        String encryptedText = reply.getString("value");
        entity.getContent().close();

        req = new JSONObject();
        req.put("alg", KEY_ENCRYPT_ALG);
        req.put("value", encryptedText);
        payload = req.toString().getBytes("UTF-8");
        System.out.println("Payload is "+req.toString()+" "+payload.length);

        message = new ByteArrayInputStream(payload);

        reqEntity = new InputStreamEntity(message, -1, JsonContentType);
        reqEntity.setChunked(true);

        ub = new URIBuilder(
                "https://aexpress-dev1-key-vault.vault.azure.net/keys/"+KEY_NAME+"/decrypt?api-version=2014-12-08-preview");
        uri = ub.build();
        request = RequestBuilder.post().setUri(uri)
                .setHeader(HttpHeaders.AUTHORIZATION, "Bearer "+res.getAccessToken())
                .setEntity(reqEntity).build();
        response = client.execute(request);
        status = response.getStatusLine().getStatusCode();
        entity = response.getEntity();
        body = null;
        if(entity==null) {
            System.err.println("No body");
            throw new ClientProtocolException("Response has no body");
        }
        else {
            body = EntityUtils.toString(entity);
        }


    }
}

Apache Http 客户端的输出是

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
2015/04/09 17:16:40:939 BST [DEBUG] RequestAddCookies - CookieSpec selected: best-match
2015/04/09 17:16:40:970 BST [DEBUG] RequestAuthCache - Auth cache not set in the context
2015/04/09 17:16:40:970 BST [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
2015/04/09 17:16:41:002 BST [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
2015/04/09 17:16:41:002 BST [DEBUG] MainClientExec - Opening connection {s}->https://aexpress-dev1-key-vault.vault.azure.net:443
2015/04/09 17:16:41:143 BST [DEBUG] HttpClientConnectionOperator - Connecting to aexpress-dev1-key-vault.vault.azure.net/191.235.161.98:443
2015/04/09 17:16:41:268 BST [DEBUG] HttpClientConnectionOperator - Connection established 192.168.0.216:57719<->191.235.161.98:443
2015/04/09 17:16:41:268 BST [DEBUG] MainClientExec - Executing request POST /keys/TestKey1/encrypt?api-version=2014-12-08-preview HTTP/1.1
2015/04/09 17:16:41:268 BST [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> POST /keys/TestKey1/encrypt?api-version=2014-12-08-preview HTTP/1.1
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Authorization: Bearer .... snip ... a real bearer code
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Transfer-Encoding: chunked
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Content-Type: application/json
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Host: aexpress-dev1-key-vault.vault.azure.net
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Connection: Keep-Alive
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
2015/04/09 17:16:41:284 BST [DEBUG] headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "POST /keys/TestKey1/encrypt?api-version=2014-12-08-preview HTTP/1.1[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Authorization: Bearer .... snip ... a real bearer code[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Transfer-Encoding: chunked[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Content-Type: application/json[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Host: aexpress-dev1-key-vault.vault.azure.net[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.3.6 (java 1.5)[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "2e[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "{"alg":"RSA1_5","value":"VGhpcyBpcyBhIHRlc3Q"}[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "0[\r][\n]"
2015/04/09 17:16:41:284 BST [DEBUG] wire - http-outgoing-0 >> "[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "HTTP/1.1 200 OK[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "Cache-Control: no-cache[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "Pragma: no-cache[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "Content-Type: application/json; charset=utf-8[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "Expires: -1[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "Server: Microsoft-IIS/8.5[\r][\n]"
2015/04/09 17:16:41:346 BST [DEBUG] wire - http-outgoing-0 << "x-ms-keyvault-service-version: 1.0.0.82[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "X-AspNet-Version: 4.0.30319[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "X-Powered-By: ASP.NET[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "Strict-Transport-Security: max-age=31536000;includeSubDomains[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "Date: Thu, 09 Apr 2015 16:16:41 GMT[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "Content-Length: 457[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "[\r][\n]"
2015/04/09 17:16:41:362 BST [DEBUG] wire - http-outgoing-0 << "{"kid":"https://aexpress-dev1-key-vault.vault.azure.net/keys/TestKey1/a23c0f08a4ef453ba8f2ab80c468e8ae","value":"m575654yUIZNml4-pBjL2hBZEdhr8P11uAbylFpMEO-7RQA7L-WpyDq2WV5YjDPHtnGNrMZb-rOyw-vC1uh9_WlhhA3wdlYaRohj_OMFZTzzLR3Zt0Sc7egIGoIqdoJBgu-INh2rV2GuwmBd9jthSuVnp_qyVfOJsDXrCvsrgjT0aLBHa3QX54G75GzzuV1bE351YRC9klj8C1bg19Qd_BiZ_b9B0eGXBKBNmDbR2-AjfxUhlMALVWROTDTeABW60cs4ZMqi5HnQYyKulKK5CyvZD0lYmQH54PPWjIFuC__xkPF8_0W4Z3Ri8Nz4616LosKWL7EQjR87lZAwF9Ypdw"}"
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << HTTP/1.1 200 OK
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Cache-Control: no-cache
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Pragma: no-cache
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Content-Type: application/json; charset=utf-8
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Expires: -1
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Server: Microsoft-IIS/8.5
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << x-ms-keyvault-service-version: 1.0.0.82
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << X-AspNet-Version: 4.0.30319
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << X-Powered-By: ASP.NET
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Strict-Transport-Security: max-age=31536000;includeSubDomains
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Date: Thu, 09 Apr 2015 16:16:41 GMT
2015/04/09 17:16:41:362 BST [DEBUG] headers - http-outgoing-0 << Content-Length: 457
2015/04/09 17:16:41:362 BST [DEBUG] MainClientExec - Connection can be kept alive indefinitely
2015/04/09 17:16:41:362 BST [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443] can be kept alive indefinitely
2015/04/09 17:16:41:362 BST [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
2015/04/09 17:16:41:377 BST [DEBUG] RequestAddCookies - CookieSpec selected: best-match
2015/04/09 17:16:41:377 BST [DEBUG] RequestAuthCache - Auth cache not set in the context
2015/04/09 17:16:41:377 BST [DEBUG] PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
2015/04/09 17:16:41:377 BST [DEBUG] PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
2015/04/09 17:16:41:377 BST [DEBUG] MainClientExec - Stale connection check
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 << "[read] I/O error: Read timed out"
2015/04/09 17:16:41:393 BST [DEBUG] MainClientExec - Executing request POST /keys/TestKey1/decrypt?api-version=2014-12-08-preview HTTP/1.1
2015/04/09 17:16:41:393 BST [DEBUG] MainClientExec - Proxy auth state: UNCHALLENGED
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> POST /keys/TestKey1/decrypt?api-version=2014-12-08-preview HTTP/1.1
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Authorization: Bearer .... snip ... a real bearer code
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Transfer-Encoding: chunked
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Content-Type: application/json
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Host: aexpress-dev1-key-vault.vault.azure.net
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Connection: Keep-Alive
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.3.6 (java 1.5)
2015/04/09 17:16:41:393 BST [DEBUG] headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "POST /keys/TestKey1/decrypt?api-version=2014-12-08-preview HTTP/1.1[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Authorization: Bearer .... snip ... a real bearer code[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Transfer-Encoding: chunked[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Content-Type: application/json[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Host: aexpress-dev1-key-vault.vault.azure.net[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.3.6 (java 1.5)[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "171[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "{"alg":"RSA1_5","value":"m575654yUIZNml4-pBjL2hBZEdhr8P11uAbylFpMEO-7RQA7L-WpyDq2WV5YjDPHtnGNrMZb-rOyw-vC1uh9_WlhhA3wdlYaRohj_OMFZTzzLR3Zt0Sc7egIGoIqdoJBgu-INh2rV2GuwmBd9jthSuVnp_qyVfOJsDXrCvsrgjT0aLBHa3QX54G75GzzuV1bE351YRC9klj8C1bg19Qd_BiZ_b9B0eGXBKBNmDbR2-AjfxUhlMALVWROTDTeABW60cs4ZMqi5HnQYyKulKK5CyvZD0lYmQH54PPWjIFuC__xkPF8_0W4Z3Ri8Nz4616LosKWL7EQjR87lZAwF9Ypdw"}[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "0[\r][\n]"
2015/04/09 17:16:41:393 BST [DEBUG] wire - http-outgoing-0 >> "[\r][\n]"
Payload is {"alg":"RSA1_5","value":"m575654yUIZNml4-pBjL2hBZEdhr8P11uAbylFpMEO-7RQA7L-WpyDq2WV5YjDPHtnGNrMZb-rOyw-vC1uh9_WlhhA3wdlYaRohj_OMFZTzzLR3Zt0Sc7egIGoIqdoJBgu-INh2rV2GuwmBd9jthSuVnp_qyVfOJsDXrCvsrgjT0aLBHa3QX54G75GzzuV1bE351YRC9klj8C1bg19Qd_BiZ_b9B0eGXBKBNmDbR2-AjfxUhlMALVWROTDTeABW60cs4ZMqi5HnQYyKulKK5CyvZD0lYmQH54PPWjIFuC__xkPF8_0W4Z3Ri8Nz4616LosKWL7EQjR87lZAwF9Ypdw"} 369
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "HTTP/1.1 400 Bad Request[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Cache-Control: no-cache[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Pragma: no-cache[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Content-Length: 72[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Content-Type: application/json; charset=utf-8[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Expires: -1[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Server: Microsoft-IIS/8.5[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "x-ms-keyvault-service-version: 1.0.0.82[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "X-AspNet-Version: 4.0.30319[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "X-Powered-By: ASP.NET[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Strict-Transport-Security: max-age=31536000;includeSubDomains[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "Date: Thu, 09 Apr 2015 16:16:41 GMT[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "[\r][\n]"
2015/04/09 17:16:41:459 BST [DEBUG] wire - http-outgoing-0 << "{"error":{"code":"BadParameter","message":"Request body not specified"}}"
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << HTTP/1.1 400 Bad Request
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Cache-Control: no-cache
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Pragma: no-cache
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Content-Length: 72
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Content-Type: application/json; charset=utf-8
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Expires: -1
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Server: Microsoft-IIS/8.5
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << x-ms-keyvault-service-version: 1.0.0.82
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << X-AspNet-Version: 4.0.30319
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << X-Powered-By: ASP.NET
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Strict-Transport-Security: max-age=31536000;includeSubDomains
2015/04/09 17:16:41:459 BST [DEBUG] headers - http-outgoing-0 << Date: Thu, 09 Apr 2015 16:16:41 GMT
2015/04/09 17:16:41:459 BST [DEBUG] MainClientExec - Connection can be kept alive indefinitely
400
2015/04/09 17:16:41:459 BST [DEBUG] PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443] can be kept alive indefinitely
2015/04/09 17:16:41:459 BST [DEBUG] PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://aexpress-dev1-key-vault.vault.azure.net:443][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]

最佳答案

问题似乎是对于解密消息,必须关闭分块传输编码并提供内容长度;

 reqEntity = new InputStreamEntity(message, -1, JsonContentType);
 reqEntity.setChunked(true);

应该是

 reqEntity = new InputStreamEntity(message, payload.length, JsonContentType);
 reqEntity.setChunked(false);

完整代码;

@Test
public void testEncryptWithKey2() throws InterruptedException, ExecutionException, JSONException, URISyntaxException, ClientProtocolException, IOException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException
{
    AuthenticationContext ctx = new AuthenticationContext(AAD_TENANT_ENDPOINT, true, Executors.newFixedThreadPool(1));
    Future<AuthenticationResult> resp = ctx.acquireToken("https://vault.azure.net", new ClientCredential(AAD_CLIENT_ID, AAD_CLIENT_SECRET), null);
    AuthenticationResult res = resp.get();
    String auth_token = res.getAccessToken();


    String plainText = "This is another test";
    String plainTextB64Encoded = Base64.encodeBase64URLSafeString(plainText.getBytes("UTF-8"));
    JSONObject req = new JSONObject();
    req.put("alg", KEY_ENCRYPT_ALG);
    req.put("value", plainTextB64Encoded);
    byte[] payload = req.toString().getBytes("UTF-8");

    ByteArrayInputStream message = new ByteArrayInputStream(req.toString().getBytes("UTF-8"));      
    InputStreamEntity reqEntity = new InputStreamEntity(message, payload.length, JsonContentType);
    reqEntity.setChunked(false);

    URIBuilder ub = new URIBuilder(
            "https://aexpress-dev1-key-vault.vault.azure.net/keys/"+KEY_NAME+"/encrypt?api-version="+API_VERSION);
    URI uri = ub.build();
    HttpUriRequest request = RequestBuilder.post().setUri(uri)
            .setHeader(HttpHeaders.AUTHORIZATION, "Bearer "+auth_token)
            .setEntity(reqEntity).build();
    HttpClient client = HttpClientBuilder.create().build();
    HttpResponse response = client.execute(request);
    int status = response.getStatusLine().getStatusCode();
    HttpEntity entity = response.getEntity();
    String body = null;
    if(entity==null) {
        System.err.println("No body");
        throw new ClientProtocolException("Request failed: Response has no body status: "+status);
    }
    else {
        body = EntityUtils.toString(entity);
        if(status < 200 || status > 299)
        {
            System.out.println("Got error reply: " +body);
            throw new ClientProtocolException("Request failed: "+body+" status: "+status);
        }
    }
    JSONObject reply = new JSONObject(body);
    String encryptedText = reply.getString("value");
    entity.getContent().close();

    req = new JSONObject();
    req.put("alg", KEY_ENCRYPT_ALG);
    req.put("value", encryptedText);
    payload = req.toString().getBytes("UTF-8");

    message = new ByteArrayInputStream(payload);

    reqEntity = new InputStreamEntity(message, payload.length, JsonContentType);
    reqEntity.setChunked(false);

    ub = new URIBuilder(
            "https://aexpress-dev1-key-vault.vault.azure.net/keys/"+KEY_NAME+"/decrypt?api-version="+API_VERSION);
    uri = ub.build();
    request = RequestBuilder.post().setUri(uri)
            .setHeader(HttpHeaders.AUTHORIZATION, "Bearer "+auth_token)
            .setHeader("client-request-id", UUID.randomUUID().toString())
            .setEntity(reqEntity).build();
    response = client.execute(request);
    status = response.getStatusLine().getStatusCode();
    entity = response.getEntity();
    body = null;
    if(entity==null) {
        System.err.println("No body");
        throw new ClientProtocolException("Request failed: Response has no body status: "+status);
    }
    else {
        body = EntityUtils.toString(entity);
        if(status < 200 || status > 299)
        {
            System.out.println("Got error reply: " +body);
            throw new ClientProtocolException("Request failed: "+body+" status: "+status);
        }
    }
    reply = new JSONObject(body);
    String base64encodedDecryptedText = reply.getString("value");
    String decryptedText = new String(Base64.decodeBase64(base64encodedDecryptedText), "UTF-8");
    System.out.println(decryptedText.toString());
    Assert.assertTrue("Text did not decrypt to the same value", plainText.equals(decryptedText));
}

c# .net 示例对于调试问题很有用,因为它适用于它包含的所有操作。背景可以在Rahul Nath's blog找到。 取消注释该行

ServicePointManager.ServerCertificateValidationCallback += ( sender, cert, chain, sslPolicyErrors ) => true;

并运行示例 here与 Fiddler 对抗以查明线路上发生了什么;不要在生产代码上这样做:-)

关于java - Azure key 保管库。无法使用相同的 key 和算法解密返回的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29544198/

相关文章:

c# - 凯撒密码 (C#)

java - 如何从JsonNode对象中检索以特定字母开头的JSON元素列表?

java - 使用 ProGuard 后应用程序在移动设备上崩溃

java - 使用 jfilechooser 的问题

powershell - 用于交换 Azure 应用服务(网站)部署槽的 Azure Powershell 脚本

java - java AES解密函数有什么问题?

java - RESTEasy 是否有一个好的 BrowserCache 实现? (比 LightweightBrowserCache 更好)

azure - 如何通过 docker CLI/quickstart 终端创建 Azure VM 并配置容器以使用 Azure 文件存储?

azure - 如何在 Microsoft Azure 上部署简单的静态微型网站

java - 解码 UTF-8 字符串