MAT, hash, dan tanda tangan

Artikel ini membahas bagaimana kode autentikasi pesan (MAC), hash, dan tanda tangan dapat digunakan di aplikasi Platform Windows Universal (UWP) untuk mendeteksi perubahan pesan.

Kode autentikasi pesan (MAC)

Enkripsi membantu mencegah individu yang tidak sah membaca pesan, tetapi tidak mencegah individu tersebut mengubah pesan. Pesan yang diubah, bahkan jika perubahan menghasilkan apa-apa selain omong kosong, dapat memiliki biaya nyata. Kode autentikasi pesan (MAC) membantu mencegah perubahan pesan. Misalnya, pertimbangkan skenario berikut:

  • Bob dan Alice berbagi kunci rahasia dan menyetujui fungsi MAC untuk digunakan.
  • Bob membuat pesan dan memasukkan pesan dan kunci rahasia ke dalam fungsi MAC untuk mengambil nilai MAC.
  • Bob mengirim pesan [tidak terenkripsi] dan nilai MAC ke Alice melalui jaringan.
  • Alice menggunakan kunci rahasia dan pesan sebagai input ke fungsi MAC. Dia membandingkan nilai MAC yang dihasilkan dengan nilai MAC yang dikirim oleh Bob. Jika sama, pesan tidak diubah saat transit.

Perhatikan bahwa Eve, pihak ketiga yang menguping percakapan antara Bob dan Alice, tidak dapat memanipulasi pesan secara efektif. Eve tidak memiliki akses ke kunci privat dan tidak dapat, oleh karena itu, buat nilai MAC yang akan membuat pesan yang dirusak tampak sah kepada Alice.

Membuat kode autentikasi pesan memastikan hanya bahwa pesan asli tidak diubah dan, dengan menggunakan kunci rahasia bersama, bahwa hash pesan ditandatangani oleh seseorang dengan akses ke kunci privat tersebut.

Anda dapat menggunakan MacAlgorithmProvider untuk menghitung algoritma MAC yang tersedia dan menghasilkan kunci konten. Anda dapat menggunakan metode statis pada kelas CryptographicEngine untuk melakukan enkripsi yang diperlukan yang membuat nilai MAC.

Tanda tangan digital adalah kunci umum yang setara dengan kode autentikasi pesan kunci privat (MAC). Meskipun MAC menggunakan kunci privat untuk memungkinkan penerima pesan memverifikasi bahwa pesan belum diubah selama transmisi, tanda tangan menggunakan pasangan kunci privat/publik.

Contoh kode ini menunjukkan cara menggunakan kelas MacAlgorithmProvider untuk membuat kode autentikasi pesan yang di-hash (HMAC).

using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

namespace SampleMacAlgorithmProvider
{
    sealed partial class MacAlgProviderApp : Application
    {
        public MacAlgProviderApp()
        {
            // Initialize the application.
            this.InitializeComponent();

            // Initialize the hashing process.
            String strMsg = "This is a message to be authenticated";
            String strAlgName = MacAlgorithmNames.HmacSha384;
            IBuffer buffMsg;
            CryptographicKey hmacKey;
            IBuffer buffHMAC;

            // Create a hashed message authentication code (HMAC)
            this.CreateHMAC(
                strMsg,
                strAlgName,
                out buffMsg,
                out hmacKey,
                out buffHMAC);

            // Verify the HMAC.
            this.VerifyHMAC(
                buffMsg,
                hmacKey,
                buffHMAC);
        }

        void CreateHMAC(
            String strMsg,
            String strAlgName,
            out IBuffer buffMsg,
            out CryptographicKey hmacKey,
            out IBuffer buffHMAC)
        {
            // Create a MacAlgorithmProvider object for the specified algorithm.
            MacAlgorithmProvider objMacProv = MacAlgorithmProvider.OpenAlgorithm(strAlgName);

            // Demonstrate how to retrieve the name of the algorithm used.
            String strNameUsed = objMacProv.AlgorithmName;

            // Create a buffer that contains the message to be signed.
            BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
            buffMsg = CryptographicBuffer.ConvertStringToBinary(strMsg, encoding);

            // Create a key to be signed with the message.
            IBuffer buffKeyMaterial = CryptographicBuffer.GenerateRandom(objMacProv.MacLength);
            hmacKey = objMacProv.CreateKey(buffKeyMaterial);

            // Sign the key and message together.
            buffHMAC = CryptographicEngine.Sign(hmacKey, buffMsg);

            // Verify that the HMAC length is correct for the selected algorithm
            if (buffHMAC.Length != objMacProv.MacLength)
            {
                throw new Exception("Error computing digest");
            }
         }

        public void VerifyHMAC(
            IBuffer buffMsg,
            CryptographicKey hmacKey,
            IBuffer buffHMAC)
        {
            // The input key must be securely shared between the sender of the HMAC and 
            // the recipient. The recipient uses the CryptographicEngine.VerifySignature() 
            // method as follows to verify that the message has not been altered in transit.
            Boolean IsAuthenticated = CryptographicEngine.VerifySignature(hmacKey, buffMsg, buffHMAC);
            if (!IsAuthenticated)
            {
                throw new Exception("The message cannot be verified.");
            }
        }
    }
}

Hash

Fungsi hash kriptografi mengambil blok data yang sangat panjang dan mengembalikan string bit ukuran tetap. Fungsi hash biasanya digunakan saat menandatangani data. Karena sebagian besar operasi tanda tangan kunci publik secara komputasi intensif, biasanya lebih efisien untuk menandatangani (mengenkripsi) hash pesan daripada menandatangani pesan asli. Prosedur berikut mewakili skenario umum, meskipun disederhanakan:

  • Bob dan Alice berbagi kunci rahasia dan menyetujui fungsi MAC untuk digunakan.
  • Bob membuat pesan dan memasukkan pesan dan kunci rahasia ke dalam fungsi MAC untuk mengambil nilai MAC.
  • Bob mengirim pesan [tidak terenkripsi] dan nilai MAC ke Alice melalui jaringan.
  • Alice menggunakan kunci rahasia dan pesan sebagai input ke fungsi MAC. Dia membandingkan nilai MAC yang dihasilkan dengan nilai MAC yang dikirim oleh Bob. Jika sama, pesan tidak diubah saat transit.

Perhatikan bahwa Alice mengirim pesan yang tidak terenkripsi. Hanya hash yang dienkripsi. Prosedur ini memastikan hanya bahwa pesan asli tidak diubah dan, dengan menggunakan kunci umum Alice, bahwa hash pesan ditandatangani oleh seseorang dengan akses ke kunci privat Alice, mungkin Alice.

Anda dapat menggunakan kelas HashAlgorithmProvider untuk menghitung algoritma hash yang tersedia dan membuat nilai CryptographicHash .

Tanda tangan digital adalah kunci umum yang setara dengan kode autentikasi pesan kunci privat (MAC). Sedangkan MAC menggunakan kunci privat untuk mengaktifkan penerima pesan untuk memverifikasi bahwa pesan belum diubah selama transmisi, tanda tangan menggunakan pasangan kunci privat/publik.

Objek CryptographicHash dapat digunakan untuk berulang kali melakukan hash data yang berbeda tanpa harus membuat ulang objek untuk setiap penggunaan. Metode Tambahkan menambahkan data baru ke buffer yang akan di-hash. Metode GetValueAndReset hash data dan mengatur ulang objek untuk penggunaan lain. Ini ditunjukkan oleh contoh berikut.

public void SampleReusableHash()
{
    // Create a string that contains the name of the hashing algorithm to use.
    String strAlgName = HashAlgorithmNames.Sha512;

    // Create a HashAlgorithmProvider object.
    HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(strAlgName);

    // Create a CryptographicHash object. This object can be reused to continually
    // hash new messages.
    CryptographicHash objHash = objAlgProv.CreateHash();

    // Hash message 1.
    String strMsg1 = "This is message 1.";
    IBuffer buffMsg1 = CryptographicBuffer.ConvertStringToBinary(strMsg1, BinaryStringEncoding.Utf16BE);
    objHash.Append(buffMsg1);
    IBuffer buffHash1 = objHash.GetValueAndReset();

    // Hash message 2.
    String strMsg2 = "This is message 2.";
    IBuffer buffMsg2 = CryptographicBuffer.ConvertStringToBinary(strMsg2, BinaryStringEncoding.Utf16BE);
    objHash.Append(buffMsg2);
    IBuffer buffHash2 = objHash.GetValueAndReset();

    // Hash message 3.
    String strMsg3 = "This is message 3.";
    IBuffer buffMsg3 = CryptographicBuffer.ConvertStringToBinary(strMsg3, BinaryStringEncoding.Utf16BE);
    objHash.Append(buffMsg3);
    IBuffer buffHash3 = objHash.GetValueAndReset();

    // Convert the hashes to string values (for display);
    String strHash1 = CryptographicBuffer.EncodeToBase64String(buffHash1);
    String strHash2 = CryptographicBuffer.EncodeToBase64String(buffHash2);
    String strHash3 = CryptographicBuffer.EncodeToBase64String(buffHash3);
}

Tanda tangan digital

Tanda tangan digital adalah kunci umum yang setara dengan kode autentikasi pesan kunci privat (MAC). Sedangkan MAC menggunakan kunci privat untuk mengaktifkan penerima pesan untuk memverifikasi bahwa pesan belum diubah selama transmisi, tanda tangan menggunakan pasangan kunci privat/publik.

Karena sebagian besar operasi tanda tangan kunci publik secara komputasi intensif, namun, biasanya lebih efisien untuk menandatangani (mengenkripsi) hash pesan daripada menandatangani pesan asli. Pengirim membuat hash pesan, menandatanganinya, dan mengirim tanda tangan dan pesan (tidak terenkripsi). Penerima menghitung hash atas pesan, mendekripsi tanda tangan, dan membandingkan tanda tangan yang didekripsi dengan nilai hash. Jika cocok, penerima dapat cukup yakin bahwa pesan itu, pada kenyataannya, berasal dari pengirim dan tidak diubah selama transmisi.

Penandatanganan hanya memastikan bahwa pesan asli tidak diubah dan, dengan menggunakan kunci publik pengirim, bahwa hash pesan ditandatangani oleh seseorang dengan akses ke kunci privat.

Anda dapat menggunakan objek AsymmetricKeyAlgorithmProvider untuk menghitung algoritma tanda tangan yang tersedia dan menghasilkan atau mengimpor pasangan kunci. Anda dapat menggunakan metode statis pada kelas CryptographicHash untuk menandatangani pesan atau memverifikasi tanda tangan.