Hmac-sha256签名和验证

    技术2022-07-14  58

    下面的示例演示如何使用 HMACSHA256 对象,然后验证文件的方法来对文件进行签名。

    C#

    using System; using System.IO; using System.Security.Cryptography;

    public class HMACSHA256example {

        public static void Main(string[] Fileargs)     {         string dataFile;         string signedFile;         //If no file names are specified, create them.         if (Fileargs.Length < 2)         {             dataFile = @"text.txt";             signedFile = "signedFile.enc";

                if (!File.Exists(dataFile))             {                 // Create a file to write to.                 using (StreamWriter sw = File.CreateText(dataFile))                 {                     sw.WriteLine("Here is a message to sign");                 }             }         }         else         {             dataFile = Fileargs[0];             signedFile = Fileargs[1];         }         try         {             // Create a random key using a random number generator. This would be the             //  secret key shared by sender and receiver.             byte[] secretkey = new Byte[64];             //RNGCryptoServiceProvider is an implementation of a random number generator.             using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())             {                 // The array is now filled with cryptographically strong random bytes.                 rng.GetBytes(secretkey);

                    // Use the secret key to sign the message file.                 SignFile(secretkey, dataFile, signedFile);

                    // Verify the signed file                 VerifyFile(secretkey, signedFile);             }         }         catch (IOException e)         {             Console.WriteLine("Error: File not found", e);         }     }  //end main     // Computes a keyed hash for a source file and creates a target file with the keyed hash     // prepended to the contents of the source file.     public static void SignFile(byte[] key, String sourceFile, String destFile)     {         // Initialize the keyed hash object.         using (HMACSHA256 hmac = new HMACSHA256(key))         {             using (FileStream inStream = new FileStream(sourceFile, FileMode.Open))             {                 using (FileStream outStream = new FileStream(destFile, FileMode.Create))                 {                     // Compute the hash of the input file.                     byte[] hashValue = hmac.ComputeHash(inStream);                     // Reset inStream to the beginning of the file.                     inStream.Position = 0;                     // Write the computed hash value to the output file.                     outStream.Write(hashValue, 0, hashValue.Length);                     // Copy the contents of the sourceFile to the destFile.                     int bytesRead;                     // read 1K at a time                     byte[] buffer = new byte[1024];                     do                     {                         // Read from the wrapping CryptoStream.                         bytesRead = inStream.Read(buffer, 0, 1024);                         outStream.Write(buffer, 0, bytesRead);                     } while (bytesRead > 0);                 }             }         }         return;     } // end SignFile

        // Compares the key in the source file with a new key created for the data portion of the file. If the keys     // compare the data has not been tampered with.     public static bool VerifyFile(byte[] key, String sourceFile)     {         bool err = false;         // Initialize the keyed hash object.         using (HMACSHA256 hmac = new HMACSHA256(key))         {             // Create an array to hold the keyed hash value read from the file.             byte[] storedHash = new byte[hmac.HashSize / 8];             // Create a FileStream for the source file.             using (FileStream inStream = new FileStream(sourceFile, FileMode.Open))             {                 // Read in the storedHash.                 inStream.Read(storedHash, 0, storedHash.Length);                 // Compute the hash of the remaining contents of the file.                 // The stream is properly positioned at the beginning of the content,                 // immediately after the stored hash value.                 byte[] computedHash = hmac.ComputeHash(inStream);                 // compare the computed hash with the stored value

                    for (int i = 0; i < storedHash.Length; i++)                 {                     if (computedHash[i] != storedHash[i])                     {                         err = true;                     }                 }             }         }         if (err)         {             Console.WriteLine("Hash values differ! Signed file has been tampered with!");             return false;         }         else         {             Console.WriteLine("Hash values agree -- no tampering occurred.");             return true;         }     } //end VerifyFile } //end class

    注解 HMACSHA256 是一种加密哈希算法,它是从 SHA-256 哈希函数构建的,用作基于哈希的消息验证代码(HMAC)。 HMAC 进程将密钥与消息数据混合,使用哈希函数对结果进行哈希运算,再次混合使用密钥的哈希值,然后再次应用哈希函数。 输出哈希的长度为256位。

    如果发送方和接收方共享密钥,则可以使用 HMAC 来确定通过不安全通道发送的消息是否已被篡改。 发件人计算原始数据的哈希值,并以单个消息形式发送原始数据和哈希值。 接收方重新计算收到的消息上的哈希值,并检查计算的 HMAC 是否与传输的 HMAC 匹配。

    对数据或哈希值所做的任何更改都将导致不匹配,因为更改消息和重现正确的哈希值需要使用机密密钥知识。 因此,如果原始和计算所得的哈希值匹配,则将对消息进行身份验证。

    HMACSHA256 接受任意大小的密钥,并产生长度为256位的哈希序列。

    Processed: 0.009, SQL: 9