【发布时间】:2014-11-10 09:56:55
【问题描述】:
我正在尝试加密 C# 客户端和 iSeries 服务器之间的通信,但遇到了一些问题。我正在尝试使用 Diffie Hellman 创建共享密钥,但共享密钥不匹配。
我在 C# 中使用 Bouncy Castle,在 iSeries 上使用 QC3* API。步骤是:
- C# 客户端生成 DH 参数并将它们与客户端公钥一起发送到服务器。
- C服务程序解码参数并调用QC3GENDK创建服务器公钥。
- 服务器使用客户端公钥调用 QC3CALDS 以生成共享密钥。
- 服务器公钥被发送回客户端。
- 使用客户端私钥初始化的 Bouncy Castle Basic DH 协议
- 客户端使用根据第 1 步中的参数和服务器公钥生成的 DHPublicKeyParameters 调用 CalculateAgreement。
数据来回发送的方式是转换为 HEX 字符串并在每一侧进行解码。 EBCDIC 和 ASCII 之间的转换发生在 iSeries 上的服务程序中。所以例如客户端公钥转换如下:
- 公钥(作为 BigInteger)被转换为无符号字节数组,例如256 -> { 1, 0 }
- 字节数组转换为十六进制字符串,例如{ 1, 0 } -> "0100")
- 十六进制字符串发送到 iSeries。
-
通过以下 (RPG) 代码将十六进制字符串转换为长度为 64 的字符数组:
cvtch( %Addr (@clientKey ): %Addr(data4): 128); eval @clientKey = %Subst( @clientKey: 1: 64);地点:
data4 - 十六进制字符串
@clientKey - 64A 接收者变量
服务器密钥通过以下方式转换为十六进制:
-
在服务器上转换为十六进制字符串
cvthc ( %Addr( @serverKeyHex ): %Addr(@serverKey): 128); eval @serverKeyHex = %Subst(@serverKeyHex: 1: 128);地点:
@serverKey 是 64A serverKey
@serverKeyHex 是 128A 接收器变量
将 HEX 字符串发送到 C# 客户端
-
将 HEX 字符串解释为 BigInteger via
var serverKey = new BigInteger(serverHex, 16);
所以,共享密钥不匹配,但我不知道这是否与我如何解释密钥或发送密钥有关。感谢您的任何建议。
编辑: 举个具体的例子:
在 RPG 调试器中,我可以看到:
对于十六进制为 4F58E1463B66CAAC1BDD35C518A6B76E52E0464E635050B50C87329CFC4C154B8EA07B12AF0E0B9754D5331235805CF59ABE1BB500B4906BD03BCF6C76 的客户端公钥
EDIT2(更多信息): iSeries 上的 API 调用(用 C 语言)可以在这个要点中看到: https://gist.github.com/ximenean/a0a9193b776f301997bb
【问题讨论】:
-
在第 3 点 --
HEX string sent across to iSeries.值是如何来回“发送”的?另外,我们可以在您的 iSeries 上查看 API 调用吗? -
@user2338816 我添加了 API 调用的要点。数据通过 TCP/IP 发送 - 服务程序侦听套接字并将原始字节转换为 EBCDIC 字符串。
-
我会查看您的 API。为了强调其他人所说的,这是不是 EBCDIC 数据(也不是ASCII)。必须注意将其视为二进制数据,即不能进行任何类型编码或进行其他转换的位串。如果它在 PC 上的位级别与在您的 iSeries 调试中相同,那么到目前为止,很好。
标签: c# bouncycastle ibm-midrange