现有系统使用Bouncy Castle(.NET)生成签名,我需要使用Microsoft ECDsaCng类验证这些现有签名。
public static void InterchangeTest()
{
//AsymmetricCipherKeyPair bKeyPair_0 = Crypto.GenerateEcdsaKey();
String sPassPhrase = "bob is your uncle";
byte[] bPassPhrase = new UTF8Encoding(false).GetBytes(sPassPhrase);
int SaltBitSize = 128;
int EcdsaBitLength = 521;
byte[] bSalt = new byte[SaltBitSize / 8];
new SecureRandom().NextBytes(bSalt);
if (EcdsaBitLength != 192 && EcdsaBitLength != 256 && EcdsaBitLength != 521)
{
throw new ArgumentException("Invalid EcdsaBitLength length () " + EcdsaBitLength + " ECDSA supports 192, 256, and 521 bit lengths.");
}
string curveName = "P-" + EcdsaBitLength.ToString();
X9ECParameters ecP = NistNamedCurves.GetByName(curveName);
ECDomainParameters ecSpec = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H, ecP.GetSeed());
IAsymmetricCipherKeyPairGenerator g = GeneratorUtilities.GetKeyPairGenerator("ECDH");
g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom()));
AsymmetricCipherKeyPair aKeyPair = g.GenerateKeyPair();
ECPrivateKeyParameters mPrivateKey = (ECPrivateKeyParameters)aKeyPair.Private;
ECPublicKeyParameters mPublicKey = (ECPublicKeyParameters)aKeyPair.Public;
byte[] bPrivateKey = ((ECPrivateKeyParameters)aKeyPair.Private).D.ToByteArray();
String SignerName = "SHA-256withECDSA";
ISigner bSigner = SignerUtilities.GetSigner(SignerName);
bSigner.Init(true, aKeyPair.Private);
bSigner.BlockUpdate(bPassPhrase, 0, bPassPhrase.Length);
byte[] bouncySignature = bSigner.GenerateSignature();
ISigner bVerifier = SignerUtilities.GetSigner(SignerName);
bVerifier.Init(false, aKeyPair.Public);
bVerifier.BlockUpdate(bPassPhrase, 0, bPassPhrase.Length);
bool passed = bVerifier.VerifySignature(bouncySignature);
Console.WriteLine("Verified with Bouncy: " + passed);
var xmlImport = "<ECDSAKeyValue xmlns='http://www.w3.org/2001/04/xmldsig-more#'>\n"
+ " <DomainParameters>\n"
+ " <NamedCurve URN='urn:oid:1.3.132.0.35' />\n"
+ " </DomainParameters >\n"
+ " <PublicKey >\n"
+ " <X Value='" + ((ECPublicKeyParameters)aKeyPair.Public).Q.X.ToBigInteger().ToString() + "' xsi:type='PrimeFieldElemType' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' />\n"
+ " <Y Value='" + ((ECPublicKeyParameters)aKeyPair.Public).Q.Y.ToBigInteger().ToString() + "' xsi:type='PrimeFieldElemType' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' />\n"
+ " </PublicKey >\n"
+ " </ECDSAKeyValue>";
//using (StreamWriter outputFile = new StreamWriter(@"C:\Dev\x2.txt"))
//{
// outputFile.WriteLine(xmlImport);
//}
ECDsaCng eccImporter = new ECDsaCng();
eccImporter.FromXmlString(xmlImport, ECKeyXmlFormat.Rfc4050);
Console.WriteLine("hash algorithm = " + eccImporter.HashAlgorithm + " Probably " + CngAlgorithm.Sha256);
Console.WriteLine("Signature algorithm = " + eccImporter.SignatureAlgorithm + " Probably ECDsa");
Console.WriteLine("After import, key size = " + eccImporter.KeySize + " probably 521");
try
{
if (eccImporter.VerifyData(bPassPhrase, bouncySignature))
{
Console.WriteLine("Verified the signature from bouncy castle using .NET");
}
}
catch (CryptographicException e)
{
// "The parameter is incorrect"
Console.WriteLine("Did not verify bouncy signature with .NET because: " + e.Message);
}
CngKey msKey = CngKey.Create(CngAlgorithm.ECDsaP521, null, new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowPlaintextArchiving });
ECDsaCng ms_ecdsaCNG = new ECDsaCng(msKey);
String xmlExport = ms_ecdsaCNG.ToXmlString(ECKeyXmlFormat.Rfc4050);
eccImporter = new ECDsaCng();
eccImporter.FromXmlString(xmlExport, ECKeyXmlFormat.Rfc4050);
byte[] ms_SignedData = ms_ecdsaCNG.SignData(bPassPhrase);
Console.WriteLine("Verify .NET signature with .NET: " + ms_ecdsaCNG.VerifyData(bPassPhrase, ms_SignedData));
Console.WriteLine("Verify .NET signature with imported .NET: " + eccImporter.VerifyData(bPassPhrase, ms_SignedData));
//Console.WriteLine();
//Console.WriteLine(xmlExport);
//Console.WriteLine();
}
在我尝试用Microsoft类验证签名之前,一切都正常工作,此时它会生成一个异常,说明参数不正确。
有什么想法吗?
Maarten Bodewes是正确的。我的问题是签名是使用ASN.1/DER格式BouncyCastly编码的。MS使用较小的格式(我认为是IEEE P-1393)。所以,我用C#编写了这个小例程来转换签名。
public static byte[] ConvertDerToP1393(byte[] data)
{
byte[] b = new byte[132];
int totalLength = data[1];
int n = 0;
int offset = 4;
int thisLength = data[offset++];
if (data[offset] == 0) {
// Negative number!
++offset;
--thisLength;
}
for (int i= thisLength; i < 66; ++i) {
b[n++] = 0;
}
if (thisLength > 66) {
System.Console.WriteLine("BAD, first number is too big! " + thisLength);
} else {
for (int i = 0; i < thisLength; ++i) {
b[n++] = data[offset++];
}
}
++offset;
thisLength = data[offset++];
for (int i = thisLength; i < 66; ++i){
b[n++] = 0;
}
if (thisLength > 66) {
System.Console.WriteLine("BAD, second number is too big! " + thisLength);
} else {
for (int i = 0; i < thisLength; ++i) {
b[n++] = data[offset++];
}
}
return b;
}
虽然我只做了有限的测试,但代码已经与我的测试一起工作了。
我正在尝试使用加密来验证open-ssl签名,这是open-ssl部分: 现在在我的C代码中: 但是我总是收到验证失败的消息
为什么我的代码返回奇怪的结果? 我的代码给出了以下结果,它看起来不像是正确的计算结果:
问题内容: 我有一个外部服务,在定义的事件发生后会给我回电,并用其私钥签署他的请求。 我已经存储了如下公钥: 因此,我的工作是通过验证签名来检查请求的内容是否未更改。 这是我的算法: 但是目前,我的算法已停止在此消息的“ PublicKey publicKey = keyFactory.generatePublic(publicKeySpec)”步骤处: 那么,如何以java api接受的方式加载
我正在尝试将支付网关集成到我的nodejs应用程序中。当支付完成时,网关用支付结果将用户重定向到我的站点。结果是RSA签名的,我需要用支付网关提供的公钥来验证它。 下面是支付网关为签名验证提供的示例PHP代码。 有谁知道怎么把这件事搞定吗?
这就是我面临的问题, https://play.golang.org/p/Pq8xHAERD57 如果运行上述代码,第一个令牌JWKS对不会验证签名,但第二个会验证!但两者都在jwt中验证签名。木卫一。有什么办法可以用一个Golang图书馆来验证它吗? 奇怪的是如果你拿了失败的代币?我调试后发现函数func VerifyPKCS1v15(pub*PublicKey,hash crypto.hash
我正在编写一些代码,试图对一些数据进行签名。在将openssl生成的私钥转换为Java密钥库之后,我将Java签名类与SHA256withRSA一起使用。我试图确认openssl中Java类返回的签名,但由于某些原因,我无法让openssl进行验证。我最终需要在iOS Swift 3中实现这个签名验证,但在找到库之前,我想尝试根据openssl标准检查Java签名。 例如,我从我们的登录服务器得到