https://stackoverflow.com/questions/25262909/c-sharp-encoding-wsse-security-password-digest-with-sha-1-and-base64-not-matchin
onvif中的ws-username token 加密算法
Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) )
编码为utf-8
注意这里的加密不是使用字符串进行加密,而是字节数组;
public class WsseHelper
{
/// <summary>
/// 获取加密的字节数组
/// </summary>
/// <param name="nonce"></param>
/// <param name="createdString"></param>
/// <param name="basedPassword"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 计算指定字节数组的哈希值。
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static byte[] SHAOneHash(byte[] data)
{
using (SHA1Managed sha1 = new SHA1Managed())
{
var hash = sha1.ComputeHash(data);
return hash;
}
}
/// <summary>
/// 获取加密后的字符串
/// </summary>
/// <param name="nonce"></param>
/// <param name="createdString"></param>
/// <param name="password"></param>
/// <returns></returns>
public static string GetPasswordDigest(string nonce, string createdString, string password)
{
byte[] combined = buildBytes(nonce, createdString, password);
string output = System.Convert.ToBase64String(SHAOneHash(combined));
return output;
}
/// <summary>
/// 加密的时间戳
/// </summary>
/// <returns></returns>
public static string GetCreated()
{
return DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ");
}
/// <summary>
/// 将随机的16位字节数据加密成nonce
/// </summary>
/// <param name="nonce"></param>
/// <returns></returns>
public static string GetNonce()
{
byte[] nonce = new byte[16];
new Random().NextBytes(nonce);
return System.Convert.ToBase64String(nonce);
}
/// <summary>
/// 获取加密后的头部
/// </summary>
/// <param name="username"></param>
/// <param name="password"></param>
/// <returns></returns>
public static string GetHead(string username, string password)
{
string res = string.Empty;
string format = @"
<s:Header>
<wsse:Security xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"" xmlns:wsu=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"">
<wsse:UsernameToken>
<wsse:Username>{0}</wsse:Username>
<wsse:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"">{1}</wsse:Password>
<wsse:Nonce>{2}</wsse:Nonce>
<wsu:Created>{3}</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
";
string nonce = GetNonce();
string created = GetCreated();
string pas = GetPasswordDigest(nonce, created, password);
res = string.Format(format, username, pas, nonce, created);
return res;
}
}