我正在尝试让我的产品使用 C# 连接到 CyberSource,但是我遇到了麻烦。
简而言之,我试图在这里重现 Java 代码并将其翻译成C#
.
我最终得到的结果与他们不同。
我注释掉的东西我也试过了。
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
namespace encoder
{
class Program
{
static void Main(string[] args)
{
string body = "{\n \"encryptionType\": \"RsaOaep\","
+"\n \"targetOrigin\": \"https://example.com\"\n}";
Console.WriteLine(body);
string _merchantId = "merchant";
string keyID = "01dbbc88-0736-4d31-94ed-7b84579731b2";
string secret = "SXQgaXMgc2hhcmVkIHNlY3JldA==";
string url = "https://apitest.cybersource.com/flex/v1/keys";
//HashAlgorithm digester = new SHA256CryptoServiceProvider();
//byte[] digest = digester.ComputeHash(Encoding.UTF8.GetBytes(body));
//string value = string.Format("SHA-256={0}", System.Convert.ToBase64String(digest));
byte[] bytes = Encoding.UTF8.GetBytes(body);
SHA256Managed hashstring = new SHA256Managed();
byte[] digest = hashstring.ComputeHash(bytes);
string value = string.Format("SHA-256={0}", System.Convert.ToBase64String(digest));
Console.WriteLine("Digest: " + value);
Console.ReadLine();
string todaysDate = DateTime.Now.ToString("ddd, dd MMM yyyy HH':'mm':'ss 'GMT'");
//string todaysDate = "Mon, 01 Jan 2018 00:00:00 GMT";
Console.WriteLine("Current Time: " + todaysDate);
Dictionary<string, string> signedHeaders = new Dictionary<string, string>();
signedHeaders.Add("host", "apitest.cybersource.com");
signedHeaders.Add("date", todaysDate);
signedHeaders.Add("(request-target)", "post /flex/va/keys/");
signedHeaders.Add("digest", value);
//signedHeaders.Add("digest", "SHA-256=fRDzptXm4RRRD3pC/eoIBoHShRzjRAf7Xkj18upMtI8=");
//signedHeaders.Add("digest", "SHA-256=YljtibTei+du4xVIDxMr3HBsyLAEDuiYaag9TcU9jHA=");
signedHeaders.Add("v-c-merchant-id", _merchantId);
Console.WriteLine("Signed Headers: " + signedHeaders);
Console.ReadLine();
StringBuilder signatureString = new StringBuilder();
StringBuilder headersString = new StringBuilder();
foreach (KeyValuePair<string, string> s in signedHeaders)
{
signatureString.Append('\n').Append(s.Key).Append(": ").Append(s.Value);
headersString.Append(' ').Append(s.Key);
}
signatureString.Remove(0, 1);
headersString.Remove(0, 1);
HMACSHA256 sha256HMAC = new HMACSHA256(System.Convert.FromBase64String(secret));
sha256HMAC.Initialize();
StringBuilder signature = new StringBuilder();
byte[] hashBytes = sha256HMAC.ComputeHash(Encoding.UTF8.GetBytes(signatureString.ToString()));
signature.Append("keyid=\"").Append(keyID)
.Append("\", ").Append("algorithm=\"HmacSHA256\", ")
.Append("headers=\"").Append(headersString).Append("\", ")
.Append("digest: signature=\"").Append(System.Convert.ToBase64String(hashBytes)).Append("\"");
Console.WriteLine("Signature: " + signature);
Console.ReadLine();
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
myHttpWebRequest.Method = "POST";
myHttpWebRequest.ContentType = "application/json";
myHttpWebRequest.Headers["v-c-merchant-id"] = _merchantId;
myHttpWebRequest.Host = "apitest.cybersource.com";
//myHttpWebRequest.Headers["v-c-date"] = DateTime.Now.ToString();
myHttpWebRequest.Timeout = 30000; //' 30 second timeout'
myHttpWebRequest.KeepAlive = false;
myHttpWebRequest.Date = DateTime.Now;
//myHttpWebRequest.Date = new DateTime(2018, 1, 1, 0, 0, 0);
string strResponse = string.Empty;
byte[] myBytes;
using (Stream myOutputStream = myHttpWebRequest.GetRequestStream())
{
myBytes = System.Text.Encoding.ASCII.GetBytes(body);
myOutputStream.Write(myBytes, 0, myBytes.Length);
myOutputStream.Close();
}
//http://msdn.microsoft.com/en-us/library/system.net.webresponse.getresponsestream%28v=vs.71%29.aspx
using (WebResponse myWebResponse = myHttpWebRequest.GetResponse())
{
Stream RecieveStream = myWebResponse.GetResponseStream();
Encoding encode = Encoding.UTF8;
StreamReader readStream = new StreamReader(RecieveStream, encode);
strResponse = readStream.ReadToEnd();
}
Console.WriteLine("Response: " + strResponse);
Console.ReadLine();
}
}
我应该得到 CyberSource 的回复,但我不断收到401 unauthorized error
.
我还注意到第一个 console.writeline 得到了一个非常不同的SHA-256=lJooQmwcasZC4okGe61dGdcdlE672vGi5x0D/vmcZx8=
.
我应该得到SHA-256=YljtibTei+du4xVIDxMr3HBsyLAEDuiYaag9TcU9jHA=
。
更新
我还应该补充一点,我们无法使用 CyberSource SDK,因为我们无法使用 ILMerge 与我们的 DLL 合并。
谢谢!