gpt4 book ai didi

c# - 在 C# 中验证 Java 生成的 DSA 签名

转载 作者:行者123 更新时间:2023-11-30 05:06:41 25 4
gpt4 key购买 nike

我知道这个主题存在很多现有问题,但我找不到任何涵盖我的具体情况的现有答案。

我需要在某些 Java 代码中对字符串(URL)进行签名,并将该字符串与签名一起传递给 C# 程序。

我运行以下 Java 代码一次来生成 DSA key 对:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);

KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();

/* save the private key in a file */
byte[] privkey = priv.getEncoded();
FileOutputStream privkeyfos = new FileOutputStream("key.priv");
privkeyfos.write(privkey);
privkeyfos.close();

/* save the public key in a file */
byte[] pubkey = pub.getEncoded();
FileOutputStream pubkeyfos = new FileOutputStream("key.public");
pubkeyfos.write(pubkey);
pubkeyfos.close();

然后我使用以下代码来生成签名。

public static String Sign(String keyPath, byte[] data)
{
FileInputStream keyfis = new FileInputStream(new File(keyPath, "key.priv"));
byte[] encKey = new byte[keyfis.available()];
keyfis.read(encKey);
keyfis.close();

PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(encKey);
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);

Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");

dsa.initSign(privKey);

ByteArrayInputStream in = new ByteArrayInputStream(data);
BufferedInputStream bufin = new BufferedInputStream(in);
byte[] buffer = new byte[1024];
int len;
while ((len = bufin.read(buffer)) >= 0)
{
dsa.update(buffer, 0, len);
}
bufin.close();

byte[] realSig = dsa.sign();

return new String(Base64.encodeBase64(realSig), "UTF-8");
}

在我的 C# 代码中,我可以访问第一步中的字符串、Base64 编码签名和“key.public”文件。

任何人都可以提供将这些元素与合适的库组合在一起的代码块来确定字符串是否已被篡改?

最佳答案

我现在已经通过本文中的一些关键输入解决了这个问题:http://www.codeproject.com/KB/security/CryptoInteropSign.aspx

主要验证是使用以下 C# 函数完成的。

private static Boolean isValid(String xiString, String xiSig)
{
AsnKeyParser keyParser = new AsnKeyParser("path/to/key.public");
DSAParameters publicKey = keyParser.ParseDSAPublicKey();

DSACryptoServiceProvider DSA = new DSACryptoServiceProvider();
DSA.ImportParameters(publicKey);
DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(DSA);
UTF8Encoding UTF8 = new UTF8Encoding();
byte[] plainBytes = UTF8.GetBytes(xiString);
var sha1 = new SHA1Managed();
var hash = sha1.ComputeHash(plainBytes);
byte[] asn1SigBytes = Convert.FromBase64String(xiSig);
byte[] sigBytes = ConvertToP1363Signature(asn1SigBytes);
Boolean retVal = DSADeformatter.VerifySignature(hash, sigBytes);
return retVal;
}

这依赖于两个辅助方法。

1) AsnKeyParser 是附加到链接文章的类。本文提供了 C# 下载,我从中使用了两个文件:AsnKeyParser.cs 和 BerDecodeError.cs。我从 AsnKeyParser 中删除了 RSA 函数,以消除对 BigInteger 文件的依赖。

此类处理解析由我的 Java 代码创建的“key.public”文件。

2) 将 Java 生成的 46-48 字节 DER 编码签名转换为 C# 可接受的 DSA 签名的函数。

此函数基于链接文章评论中的代码。

private static byte[] ConvertToP1363Signature(byte[] ASN1Sig)
{
AsnParser asn = new AsnParser(ASN1Sig);
asn.NextSequence();
byte[] r = asn.NextInteger();
byte[] s = asn.NextInteger();

// Returned to caller
byte[] p1363Signature = new byte[40];

if (r.Length > 21 || (r.Length == 21 && r[0] != 0))
{
// WTF???
// Reject - signature verification failed
}
else if (r.Length == 21)
{
// r[0] = 0
// r[1]'s high bit *should* be set
Array.Copy(r, 1, p1363Signature, 0, 20);
}
else if (r.Length == 20)
{
// r[0]'s high bit *should not* be set
Array.Copy(r, 0, p1363Signature, 0, 20);
}
else
{
// fewer than 20 bytes
int len = r.Length;
int off = 20 - len;
Array.Copy(r, 0, p1363Signature, off, len);
}

if (s.Length > 21 || (s.Length == 21 && s[0] != 0))
{
// WTF???
// Reject - signature verification failed
}
else if (s.Length == 21)
{
// s[0] = 0
// s[1]'s high bit *should* be set
Array.Copy(s, 1, p1363Signature, 20, 20);
}
else if (s.Length == 20)
{
// s[0]'s high bit *should not* be set
Array.Copy(s, 0, p1363Signature, 20, 20);
}
else
{
// fewer than 20 bytes
int len = s.Length;
int off = 40 - len;
Array.Copy(s, 0, p1363Signature, off, len);
}

return p1363Signature;
}

关于c# - 在 C# 中验证 Java 生成的 DSA 签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4887286/

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