- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是设置:
我使用 .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/
我是一名优秀的程序员,十分优秀!