从密码短语构建私有 CngKey(ECDH_P384)
Building a private CngKey(ECDH_P384) from a passphrase
上下文:VS 2015 winforms,Windows7,使用 SecurityDriven Inferno 库。
我正在编写一个离线应用程序,它会生成加密文件作为电子邮件附件发送(因此不在客户端-服务器上下文中使用)。这些文件首先用 Inferno(ETM_Transform) 加密,然后与另一个文件一起发送(有时,用于重置密码),处理 DHM 密钥交换。
每个用户的 public 密钥存储在应用程序创建和保存的数据表中,允许在密钥交换过程中快速访问。然而,对于私钥,我的问题是用户(包括我自己)更愿意从密码短语重新创建他们的私钥,从而无需隐藏密钥,从而提高安全性和可移植性。所以我需要从存储的 public 密钥和哈希密码短语构建一个密钥。
这是一种合理的方法,还是针对此特定上下文可能有更好的方法?
这是一个非常简短的代码示例,它会引发异常:"The requested operation is not supported"。我应该如何将数据导入密钥?
internal static void CreateKey(string passPhrase)
{
byte[] keyType = new byte[] { 0x45, 0x43, 0x4B, 0x34 };
byte[] keyLength = new byte[] { 0x30, 0x0, 0x0, 0x0 };
CryptoRandom cr = new CryptoRandom(); // rng used for this example
byte[] prKey = cr.NextBytes(48); // salt+hash passphrase and pass it to the private key part
byte[] pbKey = cr.NextBytes(96); // the public part, if I understand the format correctly for a cngkey using ECDH_P384
byte[] blob = Utils.Combine(keyType, keyLength); // same as concat
blob = Utils.Combine(blob, pbKey, prKey);
CngKey key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);
}
您不能随机生成 public 密钥。 public 密钥是根据私钥(和曲线)计算得出的,您可能会收到以下错误消息:a) public X 与私钥的预期不匹配,以及 b) Y 坐标对于给定的 X 坐标不正确。
您需要根据您选择的私钥计算 public 密钥的值。据我所知,.Net 和 Windows CNG 都没有公开该功能。
CngKey
DHM blob 具有特定格式,其中包括 header - 它不仅仅是随机字节数组。你错过了 header,这就是你得到异常的原因。很高兴你得到一个例外,因为你试图做的事情在概念上是错误的。 ECDH_P384
并不是为每个随机 private-key 组合设计的 valid/proper 私钥。你不应该 hand-generate 一个 CngKey
- 将 CngKey
代留给相应的 CngKey
方法。
curve25519
,另一方面,是为任何随机private-key设计的有效。您可以考虑重新发明或重新实现 Minilock.
上下文:VS 2015 winforms,Windows7,使用 SecurityDriven Inferno 库。
我正在编写一个离线应用程序,它会生成加密文件作为电子邮件附件发送(因此不在客户端-服务器上下文中使用)。这些文件首先用 Inferno(ETM_Transform) 加密,然后与另一个文件一起发送(有时,用于重置密码),处理 DHM 密钥交换。
每个用户的 public 密钥存储在应用程序创建和保存的数据表中,允许在密钥交换过程中快速访问。然而,对于私钥,我的问题是用户(包括我自己)更愿意从密码短语重新创建他们的私钥,从而无需隐藏密钥,从而提高安全性和可移植性。所以我需要从存储的 public 密钥和哈希密码短语构建一个密钥。
这是一种合理的方法,还是针对此特定上下文可能有更好的方法?
这是一个非常简短的代码示例,它会引发异常:"The requested operation is not supported"。我应该如何将数据导入密钥?
internal static void CreateKey(string passPhrase)
{
byte[] keyType = new byte[] { 0x45, 0x43, 0x4B, 0x34 };
byte[] keyLength = new byte[] { 0x30, 0x0, 0x0, 0x0 };
CryptoRandom cr = new CryptoRandom(); // rng used for this example
byte[] prKey = cr.NextBytes(48); // salt+hash passphrase and pass it to the private key part
byte[] pbKey = cr.NextBytes(96); // the public part, if I understand the format correctly for a cngkey using ECDH_P384
byte[] blob = Utils.Combine(keyType, keyLength); // same as concat
blob = Utils.Combine(blob, pbKey, prKey);
CngKey key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);
}
您不能随机生成 public 密钥。 public 密钥是根据私钥(和曲线)计算得出的,您可能会收到以下错误消息:a) public X 与私钥的预期不匹配,以及 b) Y 坐标对于给定的 X 坐标不正确。
您需要根据您选择的私钥计算 public 密钥的值。据我所知,.Net 和 Windows CNG 都没有公开该功能。
CngKey
DHM blob 具有特定格式,其中包括 header - 它不仅仅是随机字节数组。你错过了 header,这就是你得到异常的原因。很高兴你得到一个例外,因为你试图做的事情在概念上是错误的。 ECDH_P384
并不是为每个随机 private-key 组合设计的 valid/proper 私钥。你不应该 hand-generate 一个 CngKey
- 将 CngKey
代留给相应的 CngKey
方法。
curve25519
,另一方面,是为任何随机private-key设计的有效。您可以考虑重新发明或重新实现 Minilock.