我正在尝试在Java中实现Diffie-Hellman key 交换,但是我很难理解该规范:



据我了解,ECDH将产生一个 secret key 。共享我的临时公共(public) key (QT)后,SDK会生成相同的 key ,因此我们以后可以交换使用相同 key 加密的JWE消息。

JSON {“MyPublicKey”:“QT”,“SDKPublicKey”:“QC”}将被签名并发送,但是我不明白我将如何使用 apv epk ,因为这些头参数已在 JWE中使用,而不是要共享的第一个 JWS 中。

在相同的规范中,他们谈论这些JWE消息,但是它们没有这些apv和epk参数。



我还阅读了RFC 7518中的示例,可以看到使用了头参数apv和epk,但是我不确定哪个头参数是JWE还是JWS?

关于如何使用nimbus-jose-jwt或任何其他Java库来实现这一点的任何想法都将非常有帮助。谢谢

最佳答案

apv(协议(protocol)PartyVInfo)和epk(星历公共(public) key )都是可选的,因此可以多种方式使用它们。例如,您可以使用apv反射(reflect)SDK版本。它们被添加到JWE header 中。

You can read more about JWE in Nimbus here

使用Nimbus JOSE的示例为:

import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.nimbusds.jose.*;
import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.jwk.ECKey;
import com.nimbusds.jose.jwk.KeyOperation;
import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.util.Base64;
import com.nimbusds.jose.util.Base64URL;

public class Security {

    public void generateJWE() throws JOSEException, URISyntaxException {
        JWEHeader jweHeader = buildJWEHeader(new Base64URL("202333517"), buildECKey());
        JWEObject jweObject = new JWEObject(jweHeader, new Payload("Hello World!"));
    }

    private JWEHeader buildJWEHeader(Base64URL apv, ECKey epk) {
        JWEHeader.Builder jweBuilder = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES, EncryptionMethod.A128GCM);
        jweBuilder.agreementPartyVInfo(apv);
        jweBuilder.ephemeralPublicKey(epk);
        return jweBuilder.build();
    }

    private ECKey buildECKey() throws URISyntaxException {
        Set<KeyOperation> keyOperations = new HashSet<>();
        keyOperations.add(KeyOperation.ENCRYPT);
        String transactionID = "73024831";
        URI x5u = new URI("https//website.certificate");
        KeyStore keystore = null; //initialize it
        List<Base64> x5c = new ArrayList<>();
        return new ECKey(Curve.P_256, new Base64URL("x"), new Base64URL("y"), KeyUse.ENCRYPTION, keyOperations, Algorithm.NONE, transactionID, x5u, new Base64URL("x5t"), new Base64URL("x5t256"), x5c, keystore);
    }
}

除了EncryptionMethod.A128GCM外,您还可以按照规范使用EncryptionMethod.A128CBC-HS256apvepk被添加到builder的JWEHeader中。
可以在JWEHeader.Builder和ECKey的构造函数中选择其他参数。我使用了ECDH-ES算法,A128GCM加密方法,P-256曲线(在ECKey生成中默认为椭圆曲线),
交易ID是一个字符串。我选择了没有清晰模式的其他参数。对于该示例,KeyStore的初始化将过于广泛。除了签名和其他功能外,加密只是JWE可以做的一件事。

08-25 12:24