c# – 显然(!).NET和Mono之间的签名不一致;单声道签名不是幂等
Google云端存储提供用于生成签名网址的
Java,C#代码示例:
https://cloud.google.com/storage/docs/access-control?hl=en#signing-code-csharp 我正在使用代码示例.使用相同的服务帐户|密钥,存储桶和对象,Java代码和C#代码(在Windows上)工作.当我在Mono / Linux上尝试C#代码时,它不起作用.错误是: Code: SignatureDoesNotMatch Message: The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method. 注入一些调试代码证实了这个错误. 这是进行签名的增强方法: private String signString(String stringToSign) { if (key == null) throw new Exception("Certificate not initialized"); CspParameters cp = new CspParameters( 24,"Microsoft Enhanced RSA and AES Cryptographic Provider",((RSACryptoServiceProvider)key.PrivateKey).CspKeyContainerInfo.KeyContainerName ); RSACryptoServiceProvider provider = new RSACryptoServiceProvider(cp); byte[] buffer = Encoding.UTF8.GetBytes(stringToSign); byte[] rawSignature = provider.SignData(buffer,CryptoConfig.MapNameToOID("SHA256")); Console.WriteLine ("signature == "); Console.WriteLine (BitConverter.ToString(rawSignature).Replace("-",string.Empty)); return Convert.ToBase64String(rawSignature); } 我希望(可能不正确)重复调用具有相同字符串值的signString,将返回相同的rawSignature和结果.在Java和Windows上,这是事实.在Mono上,价值会发生变化 String testString="helloworld"; Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString)); Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString)); Console.WriteLine("Signing '" + testString + "' == " + this.signString(testString)); 返回,缩写结果: signature == 4415768E8E2FB862... Signing 'helloworld' == RBV2jo4v... signature == 95E589C2F8DAD7ED... Signing 'helloworld' == leWJwvja... signature == 0589E4454FE4FB3A... Signing 'helloworld' == BYnkRU/k... 使用Java,使用Google示例的类似测试返回: rawSignature == 3E56F09EE9CF7D98... Signing 'helloworld' == PlbwnunP... rawSignature == 3E56F09EE9CF7D98... Signing 'helloworld' == PlbwnunP... rawSignature == 3E56F09EE9CF7D98... Signing 'helloworld' == PlbwnunP... 我究竟做错了什么? 解决方法
我已经设法通过完全不使用CspParameters来获得一致的结果,但使用X509Certificate2的PrivateKey属性.不幸的是,我当前的“可移植”实现需要一个让我感到紧张的演员表,但它确实在Windows和Linux(Mono 4.0.2下)上提供相同的结果,并且这些结果与原始示例代码相同.这是一个在Mono下工作的简短测试应用程序:
using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; public class Test { static void Main() { var key = new X509Certificate2("key.p12","notasecret"); byte[] buffer = Encoding.UTF8.GetBytes("test string"); // This is the slightly dodgy bit... var rsa = (RSACryptoServiceProvider) key.PrivateKey; byte[] signature = rsa.SignData(buffer,"SHA256"); Console.WriteLine(Convert.ToBase64String(signature)); } } 正如评论中所述,由于未知原因,这在.NET下不起作用:( 现在我还没有尝试使用它来制作任何云存储请求,但我希望它能够正常工作. 在更现代的平台上,您可以使用RSA具有 var rsa = key.GetRSAPrivateKey(); var signature = rsa.SignData( buffer,HashAlgorithmName.SHA256,RSASignaturePadding.Pkcs1); 您也可以在Mono上使用它,具体取决于您定位的版本. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |