gpt4 book ai didi

java - DSA 问题 - 使用 .NET 创建 DSA 公钥/私钥,通过 Java(android) 使用公钥

转载 作者:行者123 更新时间:2023-11-30 05:14:53 27 4
gpt4 key购买 nike

这是设置:

我使用 .NET 创建公钥/私钥对,我想签署一个字符串。我获取一个随机字符串,从中获取一个 byte[],对其进行签名,然后在 java 应用程序中获取签名。我想在java中验证它((!)我说的是Android的java)。

将公钥引入Java环境的过程:当我创建公钥时,我获取公钥的字节数组(P,Q,G,Y)和使用这些值在 Java 中创建 PublicKey。.NET 中的 P、Q、G、Y 是 byte[],我将它们转换为 sbyte[] 并在 Java 中使用这些 sbyte[],创建大整数:

byte[] byteP = new byte[] { -34, ...... -117 };

...

BigInteger p = new BigInteger(1,byteP);

...

new DSAPublicKeySpec(y, p, q, g);

为了测试该过程,我从 C# 中获取签名 byte[],将其转换为 sbyte[],然后在 Java 中使用它。

问题是,我稍后无法验证签名字符串。我得到了

java.security.SignatureException: signature bytes have invalid encoding

任何想法表示赞赏! (比如,用更好的、完全不同的方式来完成整个事情;))

最佳答案

DSA 签名实际上是两个数字,并且对于如何将其格式化为字节数组没有真正的标准。

Java 选择将其编码为包含两个 ASN.1 整数的 ASN.1 序列的 DER 编码。

.NET 选择在两个数字前面添加零,这样它们的长度正好是 20 个字节,并将它们连接起来。

要从 .NET 转换为 Java 格式,请执行以下操作(未经测试,但应该基本正确):

public byte[] ConvertToDsaSignatureToJavaEncoding(byte[] dsa){
if(dsa.Length!=40)
throw new ArgumentException("dsa", "DSA signature should always be 40 bytes long");
// Split into r and s.
byte[] r = new byte[20];
Array.Copy(dsa, 0, r, 0, 20);
byte[] s = new byte[20];
Array.Copy(dsa, 20, s, 0, 20);

// Convert to complement-2
byte[] complementTwoR = ToComplementTwo(r);
byte[] complementTwoS = ToComplementTwo(s);

// Build the result
byte[] res = new byte[complementTwoR.Length + complementTwoS.Length + 6];
// Sequence{
res[0] = 0x30;
res[1] = (byte) (complementTwoR.Length + complementTwoS.Length + 4);
// Integer (R)
res[2] = 0x02;
res[3] = (byte) complementTwoR.Length;
Array.Copy(complementTwoR, 0, res, 4, complementTwoR.Length);
// Integer (S)
res[complementTwoR.Length + 4] = 0x02;
res[complementTwoR.Length + 5] = (byte) complementTwoS.Length;
Array.Copy(complementTwoS, 0, res, complementTwoR.Length + 6, complementTwoS.Length);

return res;
}

public byte[] ToComplementTwo(byte[] d){
// Ensure the top-bit is zero, otherwise remove unneeded zeroes
// - Find non-zero byte
int i = 0;
while (i < d.Length && d[i] == 0) i++;
// - Do we need an extra byte
int extraByte = (d[i] & 0x80) == 1 ? 1 : 0;
// - Build the result
byte[] res = new byte[d.Length-i+extraByte];
Array.Copy(d, i, res, extraByte, d.Length-i);
return res;

}

关于java - DSA 问题 - 使用 .NET 创建 DSA 公钥/私钥,通过 Java(android) 使用公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1915535/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com