我正在尝试加密C#客户端和iSeries服务器之间的通信,但遇到了一些问题。我正在尝试使用Diffie Hellman创建共享密钥,但共享密钥不匹配。
我在C#中使用Bouncy Castle,在iSeries上使用QC3 * API。步骤是:
数据来回发送的方式是转换为HEX字符串并在每一侧进行解码。 EBCDIC和ASCII之间的转换发生在iSeries上的服务程序中。例如,客户端公钥转换如下:
通过以下(RPG)代码将HEX字符串转换为长度为64的字符数组:
cvtch( %Addr (@clientKey ): %Addr(data4): 128);
eval @clientKey = %Subst( @clientKey: 1: 64);
其中:
data4 - HEX字符串
@clientKey - 64A接收器变量
,服务器密钥通过以下方式转换为Hex:
转换为服务器上的十六进制字符串
cvthc ( %Addr( @serverKeyHex ): %Addr(@serverKey): 128);
eval @serverKeyHex = %Subst(@serverKeyHex: 1: 128);
其中:
@serverKey是64A serverKey
@serverKeyHex是128A接收器变量
将HEX字符串发送到C#客户端
通过
将HEX字符串解释为BigIntegervar serverKey = new BigInteger(serverHex,16);
因此,共享密钥不匹配,但我不知道这是否与我如何解释密钥或发送它们有关。感谢您的任何建议。
编辑: 举一个具体的例子:
在RPG调试器中我可以看到:
对于其十六进制为的客户公钥:4F58E1463B66CAAC1BDD35C518A6B76E52E0464E635050B50C87329CFC4C154B8EA07B12AF0E0B9754D5331235805CF59ABE1BB500B4906BD03BCF6C7861E2E8
EDIT2(更多信息): 可以在此要点中看到iSeries上的API调用(在C中): https://gist.github.com/ximenean/a0a9193b776f301997bb
答案 0 :(得分:2)
我不知道C#端发生了什么转换,但RPG / MI端正在从字符串转换为字符串。取一个EBCDIC字符串'ABCD'这是一个完全有效的4字节二进制数,以及一个完全有效的4字节字符。在EBCDIC CCSID 37(美国英语)中,该字符串具有代码点x'C1C2C3C4'。
CVTCH将生成以下字符串:'C1C2C3C4'即,它需要一个4个字符的字符串并将其“转换”为8个字符的字符串。在CCSID 37中,即x'C3F1C3F2C3F3C3F4'。如果你把这个字符串发送到一个用ASCII解释它的客户端,它将被完全不同地解释,因为ASCII的代码点x'C1C2C3C4'是ASCII字符串'ÁÂÃÄ'
您可能希望在从IBM端发送之前将其转换为ASCII。 'C1C2C3C4'将变为'41424344'等等。