Nou*_*MRI 17 java cryptography jwe ecdh
我正在尝试用Java实现Diffie-Hellman密钥交换,但我很难理解规范:
根据JWA(RFC 7518)在直接密钥协商模式下使用曲线P-256,dT和QC完成Diffie-Hellman密钥交换过程作为本地机制,以生成一对CEK(每个方向一个),这些CEK由Transaction标识ID.此版本规范支持的参数值为:
- "alg":ECDH-ES
- "apv":SDK参考编号
- "epk":QC,采用JSON Web Key(JWK)格式
- {"kty":"EC""crv":"P-256"}
- 所有其他参数:不存在
- CEK:"kty":oct - 256位
创建以下数据的JSON对象作为要签名的JWS有效内容:
{"MyPublicKey":"QT","SDKPublicKey":"QC"}
使用JWS Compact Serialization根据JWS(RFC 7515)生成完整JSON对象的数字签名.此版本规范支持的参数值为:
- "alg":PS256或ES256
- "x5c":X.5C v3:Cert(MyPb)以及可选的链接证书
根据我的理解,ECDH将生成一个密钥.在共享我的短暂公钥(QT)之后,SDK生成相同的密钥,因此我们以后可以交换使用相同密钥加密的JWE消息.
JSON {"MyPublicKey":"QT","SDKPublicKey":"QC"}将被签名并发送,但我不明白我将如何使用apv和epk,因为这些标题参数在JWE中使用而不是在第一个JWS将被共享.
在相同的规范中,他们谈论这些JWE消息,但他们没有这些apv和epk参数.
根据JWE(RFC 7516)使用SDK使用的相同"enc"算法加密JSON对象,获得的CEK由"kid"和JWE Compact Serialization识别.此版本规范支持的参数值为:
- "alg":dir
- "enc":A128CBC-HS256或A128GCM
- "kid":交易ID
- 所有其他参数:不存在
我还阅读了RFC 7518中的示例,其中我可以看到标题params apv和epk正在使用但是我不确定哪个标题参数,JWE或JWS?
关于如何使用nimbus-jose-jwt或任何其他java库实现这一点的任何想法都会非常有用.谢谢
这两个apv(协议PartyVInfo)和epk(短暂公开密钥)是可选的,这样他们就可以以多种方式使用.例如,您可以使用apv反映SDK版本.它们被添加到JWE标头中.
使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是EncryptionMethod.A128GCM你可以EncryptionMethod.A128CBC-HS256在你的规范中使用.apv并epk添加到内部构建器中的JWEHeader.可以在JWEHeader.Builder和ECKey的构造函数中选择其他参数.我使用了ECDH-ES算法,A128GCM加密方法,P-256曲线(椭圆曲线默认为ECKey生成),事务ID是一个字符串.我选择了没有任何清晰图案的其他参数.对于该示例,KeyStore的初始化将过于宽泛.加密只是JWE可以做的一件事,在签名和其他方面.