gpt4 book ai didi

C# 使用 SHA-1 和 Base64 编码 wsse 安全 password_digest 不匹配服务器 password_digest

转载 作者:行者123 更新时间:2023-12-05 03:14:23 24 4
gpt4 key购买 nike

我正在使用一个 Web 服务,它在 soap 请求的 header 中需要 wsse 安全性,并且由创建的、随机数和密码摘要组成。 Web 服务器使用这些值来授权真正的请求。

密码摘要是使用网络服务 API 中所述的以下算法创建的:

Password Digest The OASIS Usertoken profile defines and describes the formula that computes the unique Password_Digest string submitted in the XML For Shipping API the password information used in this formula is the base 64 encoding of the SHA-1 hash of the plain text password.

The formula to use to construct the Password_Digest value is

Password_Digest = Base64(SHA-1(Nonce + Created + Base64(SHA-1(Password))))

请注意,上述算法中的 + 符号表示三个字符串的字符串连接:Nonce from xml request、Created from xml request 和密码的 SHA-1 摘要的 Base64 编码。

我正在处理一个已知已成功获得授权的示例 XML 请求。我遇到的问题是,当我尝试使用示例中提供的值重新创建密码摘要时,我得到了不同的密码摘要值。

示例值和预期的 password_digest:
随机数:4ETItj7Xc6+9sEDT5p2UjA==
创建:2014-08-04T10:22:48.994Z
密码:密码2014!
密码摘要:Ug3FRXgyAaWU8SjYHRabnAkn330=

这是我尝试重新创建 password_digest 时尝试的各种方法的输出

string nonce = "4ETItj7Xc6+9sEDT5p2UjA==";
string created = "2014-08-04T10:22:48.994Z";
string password = "Password2014!";

方法一

string passwordDigest = TestCall.encodeBase64SHA1(nonce + created + TestCall.encodeBase64SHA1(password));

private static string encodeBase64SHA1(string phrase)
{
UTF8Encoding encoder = new UTF8Encoding();
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
//passwordDigest = z5nyI25z7CBUL7l7UkTH8E8azlQ=

方法二

string passwordDigest = TestCall.encodeBase64SHA1Managed(nonce + created + TestCall.encodeBase64SHA1Managed(password));

private static string encodeBase64SHA1Managed(string phrase)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(phrase));
return Convert.ToBase64String(hash);
}
}
//passwordDigest = z5nyI25z7CBUL7l7UkTH8E8azlQ=

方法三

string passwordDigest = TestCall.encodeAsciiToBase64SHA1(nonce + created + TestCall.encodeAsciiToBase64SHA1(password));

private static string encodeAsciiToBase64SHA1(string phrase)
{
ASCIIEncoding encoder = new ASCIIEncoding();
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
//passwordDigest = z5nyI25z7CBUL7l7UkTH8E8azlQ=

方法四

string passwordDigest = TestCall.encodeBase64SHA1HexString(nonce + created + TestCall.encodeBase64SHA1HexString(password));

private static string encodeBase64SHA1HexString(string phrase)
{
UTF8Encoding encoder = new UTF8Encoding();
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(encoder.GetBytes(phrase));

StringBuilder output = new StringBuilder();
for (int i = 0; i < hashedDataBytes.Length; i++)
{
output.Append(hashedDataBytes[i].ToString("X2"));
}
return Convert.ToBase64String(Encoding.UTF8.GetBytes(output.ToString()));
}
//passwordDigest =RjE4REQyRDg5MjFGMkZCNTM2MTMwOEM1MTkzRDc1RTZCNDgwMjhCNQ==

所有方法均未创建与样本匹配的 password_digest。方法 1 - 3 至少创建了与示例具有相同字符数的 password_digest,所以我假设编码在字符串的末尾字节数匹配的意义上是部分正确的,这是否正确?

我的问题是任何人都可以使用提供的示例值帮助重新创建 password_digest 吗?

我只想提一下,这是我第一次使用 ws-security 并且几乎没有接触过 SHA-1 和字符串编码/解码,因此非常感谢任何帮助。

注意:

示例中的 nonce 字符串以“==”结尾,表明它已被编码,Nonce 元素的 xml 模式如下:

<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">4ETItj7Xc6+9sEDT5p2UjA==</wsse:Nonce>

这表明 nonce 已编码为 base64,因此我尝试再次重新运行这些方法,但使用以下行将 nonce 转换为纯文本

nonce = Encoding.UTF8.GetString(Convert.FromBase64String(nonce));
//nonce = �Dȶ>�s���@�杔�

从结果来看,我认为 API 公司不会创建这样的随机数,或者我对随机数被加密的假设是错误的,或者我没有正确解码它。

我仍然尝试使用 nonce 的新值并得到以下结果

方法一、二

//passwordDigest = WcuTBY2W06vv2/JemRuorgxMCns=

方法三

//passwordDigest = KPHT7/ojTkvI6kJCaojbp0wKFZ4=

方法四

//passwordDigest = NzRBOTM2NUQ2RjAyMjEzN0E1NEVCN0Q0NEExODU2M0U4Q0FEMDkyQg==

因此再次没有成功,方法 3 的结果与方法 1 和 2 不同,这是出乎意料的,因为之前的 nonce 方法 1、2 和 3 给出了相同的结果。

最佳答案

我玩了例子和公式,然后我发现需要先将 nounce 解码为字节,然后再应用公式

这是具有正确结果的完整示例:

class Program
{
static void Main(string[] args)
{
// Base64(SHA-1(Nonce + Created + Base64(SHA-1(Password))))

string nonce = "4ETItj7Xc6+9sEDT5p2UjA==";
string createdString = "2014-08-04T10:22:48.994Z";
string password = "Password2014!";

string basedPassword = System.Convert.ToBase64String(SHAOneHash(Encoding.UTF8.GetBytes(password)));
byte[] combined = buildBytes(nonce, createdString, basedPassword);
string output = System.Convert.ToBase64String(SHAOneHash(combined));

Console.WriteLine("result is: " + output); // Ug3FRXgyAaWU8SjYHRabnAkn330=
Console.ReadKey();
}

private static byte[] buildBytes(string nonce, string createdString, string basedPassword)
{
byte[] nonceBytes = System.Convert.FromBase64String(nonce);
byte[] time = Encoding.UTF8.GetBytes(createdString);
byte[] pwd = Encoding.UTF8.GetBytes(basedPassword);

byte[] operand = new byte[nonceBytes.Length + time.Length + pwd.Length];
Array.Copy(nonceBytes, operand, nonceBytes.Length);
Array.Copy(time, 0, operand, nonceBytes.Length, time.Length);
Array.Copy(pwd, 0, operand, nonceBytes.Length + time.Length, pwd.Length);

return operand;
}

public static byte[] SHAOneHash(byte[] data)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(data);
return hash;
}
}
}

关于C# 使用 SHA-1 和 Base64 编码 wsse 安全 password_digest 不匹配服务器 password_digest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25262909/

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