当前位置: 首页 > 工具软件 > ws-http > 使用案例 >

onvif中的ws-username token 加密算法

洪开诚
2023-12-01

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;
        }
    }


 类似资料: