是否可以使用Diffie-Hellman密钥交换算法来加密网页上的客户端 - 服务器通信而不是SSL?如果可以,有哪些缺点(即为什么标准使用需要证书颁发机构的SSL)?我的理解是,Diffie-Hellman可用于秘密建立共享密钥,然后可用于加密任何进一步的通信.
我正在开发一个项目,与Firefox中存在的新Push API集成,并且正在开发为W3C标准.
部分原因是加密数据.服务器将收到Diffie Hellman P256曲线(使用JS生成var key = subscription.getKey('p256dh');)
转换为.NET base64时的一个例子是
BOAiqZO6ucAzDlZKKhF1aLjNpU8 + R2Pfsz4bQzNpV145D + agNxvLqyu5Q2tLalK2w31RpoDHE8Sipo0m2jiX4WA =
但是我遇到了生成派生材料的问题.
var key1 = Convert.FromBase64String("<stringFromAbove>").ToList() // You can criticize my .toList inefficiencies later
// .NET doesn't like the key without these prefixes. See here
// http://stackoverflow.com/questions/24251336/import-a-public-key-from-somewhere-else-to-cngkey
// I know the bytes don't match that post, but that is because the key type is different between their example and mine.
var keyType = new byte[] { 0x45, 0x43, 0x4B, 0x31 }; …Run Code Online (Sandbox Code Playgroud) 我成功地使用Tomcat和SSL证书设置了两台Ubuntu机器.我使用Centos 6完全遵循相同的程序,但是当我尝试连接到服务器(使用Opera)时,我得到了这个:
服务器有一个弱的,短暂的Diffie-Hellman公钥
连接器如下,catalina.log中没有错误:
<Connector port="some port number"
protocol="org.apache.coyote.http11.Http11Protocol"
SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="path to jks"
keystoreType="JKS"
keystorePass="mypass1"
keyPass="mypass2" />
Run Code Online (Sandbox Code Playgroud)
使用Firefox,我得到了不受信任的通信错误.
我正在尝试使用AES加密Android上的字符串.先前使用Diffie-Hellman算法确定对称密钥,并且似乎没问题(密钥长度为128位,见下文).
不过,我得到了一个 InvalidKeyException: "Key length not 128/192/256 bits."
码:
KeyAgreement keyAgree = KeyAgreement.getInstance("DH", "BC");
keyAgree.init(this.smartphonePrivKey);
keyAgree.doPhase(serverPubKey, true);
SecretKey key = keyAgree.generateSecret("AES");
System.out.println("Key Length: " + key.getEncoded().length);
System.out.println("Key Algorithm: "+ key.getAlgorithm());
System.out.println("Key Format: "+ key.getFormat());
byte[] encrypted = null;
Cipher cipher;
try {
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
System.out.println("Allowed Key Length: "
+ cipher.getMaxAllowedKeyLength("AES"));
cipher.init(Cipher.ENCRYPT_MODE, key);
encrypted = cipher.doFinal("YEAH".getBytes("UTF8"));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) { …Run Code Online (Sandbox Code Playgroud) 我使用https://github.com/ricmoo/GMEllipticCurveCrypto使用ECDH算法生成共享密钥.
我现在必须使用如下所述的ECDH-ES算法生成派生密钥:https://tools.ietf.org/html/rfc7518#section-4.6
如果有人可以指导我生成Derived Key的方向,我非常感激
在Diffie-Hellman Key Exchange上观看YouTube视频后,我想尝试用JavaScript实现(Atwood定律).
我使用以下规则在Node.js上绘制了一个密码:
第1步:客户端和服务器就共享密钥达成一致:
客户端和服务器以512位主公钥pK开头
客户端生成512位主要私钥kC并发送powMod(3,kC,pK)
服务器生成512位主要私钥kS并发送powMod(3,kS,pK)
客户端和服务器使用powMod(响应,私钥,pK)作为共享密钥
第2步:沟通
在客户端发送数据之前,使用Stanford Javascript加密库(256位AES,HMAC身份验证,PBKDF2密码加密和CCM身份验证加密)使用共享密钥对其进行加密.
一旦服务器使用共享密钥解密数据,它就会生成一个新的512位主要私钥,并将其作为SJCL加密响应发送.
客户端和服务器使用powMod切换到新的共享密钥(3,prevSharedKey,newPrivKey)
现在我有几个问题..
与HTTPS或其他算法相比,这样的系统有多安全?这种系统最薄弱的地方是什么?
在安全性/实用性方面,使用1024位密钥以提高安全性会更好吗?HMAC/PBKDF2/CCM选项是否过度杀伤?是否值得调整共享密钥?谢谢阅读!
我有一项任务,需要使用NIST SP 800-56A第5.8.1节中描述的密钥导出函数来获取密钥材料.我不是密码学方面的专家,所以如果问题很幼稚,请原谅我.这是我到目前为止所做的:
现在我尝试使用C#(.NET 4)ECDiffieHellmanCng类使用ECDH 1.3.132.1.12生成共享密钥,如下所示:
// The GetCngKey method reads the private key from a certificate in my Personal certificate store
CngKey cngPrivateKey = GetCngKey();
ECDiffieHellmanCng ecDiffieHellmanCng = new ECDiffieHellmanCng(cngPrivateKey);
ecDiffieHellmanCng.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP256;
ecDiffieHellmanCng.KeyDerivationFunction = ?? // What do I set here
Run Code Online (Sandbox Code Playgroud)最后这样做:
ecDiffieHellmanCng.DeriveKeyMaterial(otherPartyPublicKey:);
Run Code Online (Sandbox Code Playgroud)
在哪里/如何设置其他参数算法ID,Party U Info,Party V Info?
编辑 我愿意使用像Bouncy Castle这样的其他库(只要它们可以从.NET调用)
经过搜索,我发现自己对Diffie Hellman算法中使用P和G感到困惑.有必要P是素数,G是P的原始根.
我理解安全性是基于分解两个非常大的素数的结果的难度,所以我没有问题.然而,似乎没有关于G是P的原始根的目的的可用信息很少.任何人都可以回答为什么存在这种要求(如果可能的话,带参考)?它只是增加了安全性吗?鉴于可以使用p和g的任何组合创建共享密钥,即使是不是素数的组合,我发现这很有趣.它肯定只是为了安全吗?如果是这样,它如何增加它?
提前致谢
丹尼尔
g我使用某些和参数生成了 Diffie-Hellman 密钥p,如下所示:
$ cat dhparam.pem\n-----BEGIN DH PARAMETERS-----\nMIIBCAKCAQEAnc5+uXl2K09Nrp1oxN/KbIcIYLg8HXCu9UNW7gFknkHil7OVAKHR\nKm0Dc8IjqhJpDfoNKFoDo2Vd0KB9moSkDmhFmidcXO7Q8zSq0Z4BXFTO61OMukdd\ndul1ovbleqfH4DcbCjH4LiZGICFUyGseiBakt3e2BORyjSA3IEg4hm9WvdCevWPW\nNjc9reFgL6Vua8HkOGkLB+EvRP1YT4v5hGGP/6A7WxRevx5EjF9VgojyDLMPN26C\n3c17KY2jNV0W1GEcKEciWS61QInUDBDPYNuQzTl0LucbOpJyV3BFr6pokRBaO3bI\nZYUPhjA2WSxJUeeJboJfisr+CQa9kc1dYwIBAg==\n-----END DH PARAMETERS-----\n$ openssl genpkey -paramfile dhparam.pem -out dh.pem\n$ cat dh.pem\n-----BEGIN PRIVATE KEY-----\nMIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAJ3Ofrl5ditPTa6daMTfymyH\nCGC4PB1wrvVDVu4BZJ5B4pezlQCh0SptA3PCI6oSaQ36DShaA6NlXdCgfZqEpA5o\nRZonXFzu0PM0qtGeAVxUzutTjLpHXXbpdaL25Xqnx+A3Gwox+C4mRiAhVMhrHogW\npLd3tgTkco0gNyBIOIZvVr3Qnr1j1jY3Pa3hYC+lbmvB5DhpCwfhL0T9WE+L+YRh\nj/+gO1sUXr8eRIxfVYKI8gyzDzdugt3NeymNozVdFtRhHChHIlkutUCJ1AwQz2Db\nkM05dC7nGzqScldwRa+qaJEQWjt2yGWFD4YwNlksSVHniW6CX4rK/gkGvZHNXWMC\nAQIEggEEAoIBAGJBY5qzXPRi62hzho+ebCeZMdVqGQrlc9h/1hmrlzXlna8Mu8WF\n0hp/ol8s3AAvuG2w8sMHH/D0kHj2Ptf92khH2WObWAzyybf3IubpVumw6d2KSe1j\nLhW0cJum/lbyhyGJNgdNrVlwyNcId2Z53K9TK1BQnb3/gJjM+cRZ1yyoPDTXZpLl\n1dmLz3lw+kmowyNXtl/wgzDclR16/w7JSvM+tOFCs4X1ZZF9TbQi7czc0ov101gP\nbJjbUaYNOLUQrI/vVEDmCzYIL3PDLV07gQu0FeLHnRChgdjal3xVIsp0oV+2cN7K\n/UX4xqCSBXp8ieAoJ+r7zZD44JqhMVF+d5A=\n-----END PRIVATE KEY-----\nRun Code Online (Sandbox Code Playgroud)\n\n我的理解是,密钥文件dh.pem不仅包括密钥的秘密部分,还包括生成密钥的非秘密部分g和p 参数dh.pem\xe2\x80\x94 即,是dhparam.pem.
我想重建dhparam.pem,仅 dh.pem给出。也就是说,给定 DH 密钥文件,将其参数转储为 PEM 格式。
看起来它openssl本身可能不直接支持这一点,但也许有一些不太可怕的方法可以用 shell 脚本或其他东西来提取信息?手册页openssl dhparam说:
\n\n\n该程序操作 DH 参数而不是键。
\n
\n 错误:应该有一种方法来生成和操作 DH 密钥。
相关:OpenSSL:显示 DH 参数\xe2\x80\x94 但在该问题中,它们以证书开头,而不是私钥。(而且我不知道将我的密钥变成证书的咒语。)
\n.NET (Core 3.1) 似乎支持 ECC 中的自定义曲线。所以我定义了Curve25519,并通过以下代码生成密钥对:
using System;
using System.Security.Cryptography;
namespace Curve25519
{
class Program
{
static void Main(string[] args)
{
ECCurve ecCurve = new ECCurve() // Curve25519, 32 bytes, 256 bit
{
CurveType = ECCurve.ECCurveType.PrimeMontgomery,
B = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
A = new byte[] …Run Code Online (Sandbox Code Playgroud) diffie-hellman ×10
encryption ×4
aes ×2
c# ×2
cryptography ×2
ssl ×2
.net-core ×1
android ×1
centos ×1
certificate ×1
curve-25519 ×1
ecdsa ×1
ios ×1
javascript ×1
kdf ×1
modulo ×1
node.js ×1
objective-c ×1
openssl ×1
pem ×1
primitive ×1
root ×1
tomcat ×1
x25519 ×1