Java 使用ECDH公钥包装密钥?

Java 使用ECDH公钥包装密钥?,java,cryptography,elliptic-curve,Java,Cryptography,Elliptic Curve,前言:我不知道在这里还是在加密网站上问这个问题更合适。请随意移动或删除或任何适当的SE操作 我被要求帮助更新一些加密软件。广义地说,该软件已经完成了以下步骤,其中没有一个是特别不寻常的。为了便于发布,我省略了错误处理和Provider参数: 1) 生成用于AES-128(或AES-256,经适当修改)的随机对称密钥: 2) 根据用户是否正在使用… 2a)…密钥对中的RSA公钥: // OAEP wasn't used in this software for hysterical raisin

前言:我不知道在这里还是在加密网站上问这个问题更合适。请随意移动或删除或任何适当的SE操作


我被要求帮助更新一些加密软件。广义地说,该软件已经完成了以下步骤,其中没有一个是特别不寻常的。为了便于发布,我省略了错误处理和
Provider
参数:

1) 生成用于AES-128(或AES-256,经适当修改)的随机对称密钥:

2) 根据用户是否正在使用…
2a)…密钥对中的RSA公钥:

// OAEP wasn't used in this software for hysterical raisins
Cipher wrapper = Cipher.getInstance("RSA/ECB/PKCS1Padding");
wrapper.init (Cipher.WRAP_MODE, user_RSA_PublicKey);
2b)…密码短语:

SecretKey stretched = ...passphrase stretched through a PBKDF like bcrypt...;
// I don't remember whether it's specified as "AES" or "AESWrap" here
Cipher wrapper = Cipher.getInstance("AES or AESWrap/ECB/NoPadding");
wrapper.init (Cipher.WRAP_MODE, stretched);
2c)无论哪种路由,会话密钥都被包装:

byte[] wrapped = wrapper.wrap(sessionKey);
3) 会话密钥用于使用
密码创建
密码。加密模式
与随机IV一起,然后通过它运行大量数据。这一部分相当标准,但如果您真的想了解
CipherInputStream
的用法,我可以发布它。包装好的会话密钥与加密的数据以及一堆阳光下的所有HMAC一起存储

稍后在解密时,用户提供RSA私钥或用于扩展的密码短语;软件打开对称密钥并解密数据

所有这些都已经起作用一段时间了。当然,RSA密钥对越来越大,速度也越来越慢,因此它们希望支持上述第2步的另一种可能性,即使用椭圆曲线算法生成公钥(P384 ECDH是常见情况)。这就是我们困惑的地方

Cipher wrapper=Cipher.getInstance(“RSA/ECB/PKCS1PANDING”)
调用中,似乎没有针对椭圆曲线的JCE替换算法/转换。Java文档中唯一列出的是“ECIES”,它似乎更倾向于多方密钥协议

我能找到的Java内置JCE的所有API,甚至Bouncy Castle,都只在密钥协议和传输上下文中提到ECDH密钥,它们用于生成对称密钥,而不是包装现有密钥

我觉得我们遗漏了一些东西,可能是因为错误的假设。
Cipher.wrap()
真的不是ECDH密钥的选项吗?或者是这样,但是我们需要做一些有趣的事情来创建ECIES
密码
实例?

RSA是一种加密和签名算法(或者取决于您如何看待它,两种非常相似但不同的算法)。RSA加密可以加密dat,dat是一个(较低级别)密钥,在这种情况下称为包装

DH是一种密钥协商算法,它的经典形式(也称为整数、Zp、modp或有限域/FF)和椭圆曲线形式(ECDH)。请注意,至少对于经典DH,原始协议值g^a^b mod n=g^b^a mod n有足够的数学结构,人们不愿意将其直接用作密钥,因此我们通过密钥派生函数(缩写为KDF)来运行它。我不清楚ECDH值是否真的需要KDF,至少对于常用的X9/NIST曲线,包括P384(如果您愿意,您可以查看或询问crypto.SX),但使用KDF是便宜且成熟的,所以我们这样做

我从来没有听到过任何称职的呼叫(EC)DH key transport,因为它不是。它包含在密钥交换(key exchange)中,该术语用于涵盖运输和协议的(有用的)联合

您可以使用(EC)DH创建一个加密方案,使用约定的(和派生的)值作为对称加密的密钥-就是(EC)IES。我不知道是什么让您认为IES是其他东西。现代实践是,对称加密应该经过身份验证,IES的标准化形式作为一个单独的方案使用CBC加密和HMAC身份验证,尽管您可以有效地设计一个使用例如GCM的方案

正如您所看到的,BouncyCastle提供程序提供了DH(classic)或EC IES的“带{AES,DESEDE}-CBC”(在1.56之前的版本中,有时省略了-CBC)的实现,它使用P1363a中的KDF2和SHA1、指示的CBC密码和HMAC-SHA1。“标准”(Sun/Oracle/Open)提供程序没有,但您可以将原始协议操作、KDF、对称加密和MAC结合起来,以产生相同的结果


这与和的操作类似(尽管在某些细节上有所不同)。(PGP不支持classic DH;它使用ElGamal加密代替RSA。)更不用说TLS(有时通过1.2,总是在1.3中)和SSH,它们使用classic或EC DH“exchange”(这里是交互式的,通常是短暂的,而不是至少具有接收器静态)产生一个秘密,作为对称加密和数据认证的关键材料

如果你打算进行全面升级,你能告诉我这些限制、风险等吗?我不知道是什么让你认为IES是另外一回事。我并不认为它是“其他任何东西”,因为我一开始不知道它应该是什么。主要是因为我在其他任何地方都没有遇到过这个术语,Oracle提供了关于如何将其与标准JCE API结合使用的零文档,我几乎找不到任何其他人使用
getInstance(“ECIES”)
的例子可以从中学习。但是我会接受你的建议,使用公钥来生成对称会话密钥,看看我们是否能让它工作。非常感谢。给出了基本思想,即使用DH创建的密钥材料进行对称(认证)加密。Oracle记录了(至少在某种程度上)Oracle提供程序支持的算法,而IES不支持。我承认Bouncy通常只包含最小的javadoc(类/方法/字段名和类型)。好
byte[] wrapped = wrapper.wrap(sessionKey);