我试图用Java实现Diffie-Hellman密钥交换,但我很难理解规范:
根据JWA(RFC 7518),在直接密钥协商模式下,使用曲线P-256、dT和QC完成Diffie-Hellman密钥交换过程,作为本地机制,产生一对由事务ID标识的CEK(每个方向一个)。本规范版本支持的参数值为:
创建包含以下数据的JSON对象作为要签名的JWS负载:
{“MyPublicKey”:“QT”,“SDKPublicKey”:“QC”}
根据JWS(RFC 7515)使用JWS Compact序列化生成完整JSON对象的数字签名。本规范版本支持的参数值为:
据我了解,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序列化标识。本规范版本中支持的参数值为:
我还阅读了RFC 7518中的示例,其中我可以看到使用的头参数apv和epk,但我不确定哪个头参数,JWE的还是JWS的?
任何关于如何使用nimbus jose jwt或任何其他java库实现这一点的想法都会非常有用。谢谢
我能够为A128CBC-HS256生成密钥。然而,在128GCM中仍然没有成功。使用帮助nimbus jose库添加A128CBC-HS256的工作示例。以下代码仅用于密钥生成。
还请注意,我覆盖了nimbus jose类以供使用。希望能有帮助。
private void generateSHA256SecretKey(AREQ areq, ECKey sdkPubKey, KeyPair acsKeyPair) throws Exception {
// Step 4 - Perform KeyAgreement and derive SecretKey
SecretKey Z = CustomECDH.deriveSharedSecret(sdkPubKey.toECPublicKey(), (ECPrivateKey)acsKeyPair.getPrivate(), null);
CustomConcatKDF concatKDF = new CustomConcatKDF("SHA-256");
String algIdString = "";
String partyVInfoString = areq.getSdkReferenceNumber();
int keylength = 256; //A128CBC-HS256
byte[] algID = CustomConcatKDF.encodeDataWithLength(algIdString.getBytes(StandardCharsets.UTF_8));
byte[] partyUInfo = CustomConcatKDF.encodeDataWithLength(new byte[0]);
byte[] partyVInfo = CustomConcatKDF.encodeDataWithLength(partyVInfoString.getBytes(StandardCharsets.UTF_8));
byte[] suppPubInfo = CustomConcatKDF.encodeIntData(keylength);
byte[] suppPrivInfo = CustomConcatKDF.encodeNoData();
SecretKey derivedKey = concatKDF.deriveKey(
Z,
keylength,
algID,
partyUInfo,
partyVInfo,
suppPubInfo,
suppPrivInfo);
System.out.println("Generated SHA256 DerivedKey : "+SecureUtils.bytesToHex(derivedKey.getEncoded()));
}
Nimbus(以及Jose4j)不是实现规范的最佳选择(我猜它是3D安全2. x. x)。
这些库不返回内容加密密钥,而是根据JWE规范使用它加密或解密消息。
我发现Apache CXF Jose库作为JWE/JWS/JWK实现做得很好。除了生成短暂的密钥对。但这可以很容易地用充气城堡来完成:
Security.addProvider(new BouncyCastleProvider());
ECGenParameterSpec ecGenSpec = new ECGenParameterSpec(JsonWebKey.EC_CURVE_P256);
KeyPairGenerator g = KeyPairGenerator.getInstance(ALGORITHM_SIGNATURE_EC, "BC");
g.initialize(ecGenSpec, new SecureRandom());
KeyPair keyPair = g.generateKeyPair();
可以使用以下代码生成内容加密密钥:
byte[] cek = JweUtils.getECDHKey(privateKey, publicKey, null, SDKReferenceNumber, "", 256);
并用于加密消息以获得JWE紧凑表示:
JweEncryption jweEncryption = JweUtils.getDirectKeyJweEncryption(cek, contentAlgorithm);
JweHeaders head = new JweHeaders();
head.setHeader(JoseConstants.HEADER_KEY_ID, keyId);
String encrypted = jweEncryption.encrypt(contentToEncrypt.getBytes(StandardCharsets.UTF_8), head);
或解密:
JweCompactConsumer compactConsumer = new JweCompactConsumer(encrypted);
JweHeaders head = compactConsumer.getJweHeaders();
JweDecryption jweDecryption = JweUtils.getDirectKeyJweDecryption(cek, head.getContentEncryptionAlgorithm());
JweDecryptionOutput out = jweDecryption.decrypt(encrypted);
String decrypted = out.getContentText();
apv
(协议方yvinfo)和epk
(临时公钥)都是可选的,因此它们可以以多种方式使用。例如,您可以使用apv
来反映SDK版本。它们被添加到JWE标题中。
你可以在这里阅读更多关于光环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);
}
}
而不是加密方法。A128GCM
可以使用Encryptionmethod。A128CBC-HS256
与您的规范相同。apv
和epk
被添加到JWEHeader内部的构建器中。其他参数可以在JWEHeader的构造函数中选择。生成器和ECKey。我用的是ECDH-ES算法,A128GCM加密方法,P-256曲线(ECKey生成中默认为椭圆曲线),事务ID为字符串。我选择了其他参数,没有任何明确的模式。KeyStore的初始化对于示例来说过于宽泛。在签名和其他操作中,加密只是JWE可以做的一件事。
我正在Java的一个个人项目中工作,该项目涉及通过不安全的通道发送敏感数据。我需要知道如何实现Diffie Hellman密钥交换(DHKE)在java使用其库。我知道关于它的所有密码理论,所以不需要深入细节,我只需要一个非常基本的实现,所以我可以让两个程序共享一个密钥。我从java2s.com得到了这个例子,但它并不完整: 我该怎么做呢?有人能帮我完成剩下的代码吗?
在Diffie Hellman密钥交换过程中,如果中间的人能够得到素数“p”和生成器“g”的值。他现在能破译私钥或者生成的共享秘密秘密吗?
我正在尝试将DHE_DSS实现到Go的Crypto/TLS包中。不幸的是,我似乎无法使PreMasterSecret(Z)相同,我的基本工作流程是: 提取P、G、YS 使用提供的数字签名进行验证 null 以下是我更改的一个补丁: https://08766345559465695203.googlegroups.com/attach/48587532C74B4348/crypto.patch?p
因为这是我正在生成的一个自签名证书,所以我认为我做错了什么。 我首先创建一个根CA证书,并传入私钥来签署我的证书。 方法返回true,我读到的这个值可能返回假阳性。
本文向大家介绍迪菲-赫尔曼密钥交换(Diffie–Hellman)算法原理和PHP实现版,包括了迪菲-赫尔曼密钥交换(Diffie–Hellman)算法原理和PHP实现版的使用技巧和注意事项,需要的朋友参考一下 迪菲-赫尔曼(Diffie–Hellman)是一个可以让双方在不安全的公共信道上建立秘钥的一种算法,双方后期就可以利用这个秘钥加密(如RC4)内容。 迪菲-赫尔曼(Diffie–Hellm
我有一个应用程序,它是一个SSH客户端,支持以下协商的关键算法。 diffie-hellman-group-exchange-sha1 diffie-hellman-group14-sha1 diffie-hellman-group-exchange-sha256 我没有更改SSH客户端的选项,所以我正在尝试解决SSH服务器上的问题,它正在使用Twisted。SSH服务器实际上是在Kippo蜜罐中