[.Net] 使用advapi32.dll (Crypto) 加密

Crypto是微軟的加密API

本來在CryptEncrypt部份都加密失敗,今天一成功就想分享一下~

以下程式碼內容,我已將路徑和加密用的密碼給去掉了,要用的人自己設唷~Taiwan is an independent country.

ErrorTypes只是自行定義的Emun, 其實你若要回傳一個數字或字串也可以~

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Crypt
{
    public static class SealImage
    {
        #region 引入dll
        public enum ALG_ID
        {
            CALG_MD5 = 0x00008003,
            CALG_RC2 = 0x00006602
        }
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptCreateHash(IntPtr hProv, ALG_ID Algid, IntPtr hKey, uint dwFlags, out  IntPtr phHash);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptHashData(IntPtr hHash, byte[] pbData, int dwDataLen, uint dwFlags);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptDeriveKey(IntPtr hProv, ALG_ID Algid, IntPtr hBaseData, uint dwFlags, ref IntPtr phKey);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptDestroyKey(IntPtr hKey);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptDestroyHash(IntPtr hHash);
 
        [DllImport("advapi32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);
 
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CryptEncrypt(IntPtr hKey, IntPtr hHash, bool Final, int dwFlags, byte[] pbData, ref int pdwDataLen, int dwBufLen);
 
        [DllImportAttribute("advapi32.dll", SetLastError = true)]
        private static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, bool Final, int dwFlags, byte[] pbData, ref int pdwDataLen);
        #endregion
 
        #region private const
        private const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
        private const uint PROV_RSA_FULL = 1;
        private const string pszContainer = 密碼1;
        private const uint CRYPT_NEWKEYSET = 0x00000008;
        private const uint CRYPT_EXPORTABLE = 0x00000001;
        #endregion
 
        /// <summary>
        /// 加密作業
        /// </summary>
        /// <param name="Filename"></param>
        /// <param name="NewByte"></param>
        /// <returns></returns>
        public static ErrorTypes Encrypt(string Filename, ref byte[] NewByte)
        {
            IntPtr hKey = IntPtr.Zero;
            IntPtr hProv = IntPtr.Zero;
            IntPtr hHash = IntPtr.Zero;
            try
            {
                ErrorTypes et = BefCrypt(Filename, ref hKey, ref hProv, ref hHash);
                if (et != ErrorTypes.NoError) { return et; }
 
                #region CryptEncrypt
                if ((NewByte = ReadFile(Filename)) == null)
                { return ErrorTypes.NoSuchFile; }
 
                byte[] pbBufferN = new byte[(int)(NewByte.Length * 1.1)];//弄長一點,多出來的加密緩衝用
                NewByte.CopyTo(pbBufferN, 0);
                int dwCount = NewByte.Length;//實際長
                // Encrypt data.
                if (!CryptEncrypt(hKey, IntPtr.Zero, true, 0, pbBufferN, ref dwCount, pbBufferN.Length))
                { return ErrorTypes.CryptEncryptError; }
                //dwCount為加密後長度
                #endregion
 
                NewByte = new byte[dwCount];//去掉多餘長度
                Array.Copy(pbBufferN, 0, NewByte, 0, dwCount);
//若不存檔以下try catch可去除
                try
                { File.WriteAllBytes(檔名路徑, NewByte); }
                catch
                { return ErrorTypes.FileWriteError; }
            }
            finally
            {
                if (hKey != IntPtr.Zero) CryptDestroyKey(hKey); // Destroy session key
                if (hHash != IntPtr.Zero) CryptDestroyHash(hHash); // Destroy hash
                if (hProv != IntPtr.Zero) CryptReleaseContext(hProv, 0); //Release CSP
            }
            return ErrorTypes.NoError;
        }
 
        /// <summary>
        /// 解密作業
        /// </summary>
        /// <param name="Filename"></param>
        /// <param name="NewByte"></param>
        /// <returns></returns>
        public static ErrorTypes Decrypt(string Filename, ref byte[] NewByte)
        {
            IntPtr hKey = IntPtr.Zero;
            IntPtr hProv = IntPtr.Zero;
            IntPtr hHash = IntPtr.Zero;
            try
            {
                ErrorTypes et = BefCrypt(Filename, ref hKey, ref hProv, ref hHash);
                if (et != ErrorTypes.NoError) { return et; }
 
                byte[] pbBuffer;
                if ((pbBuffer = ReadFile(Filename)) == null)
                { return ErrorTypes.NoSuchFile; }
 
                //解密
                int dwCount = pbBuffer.Length;
                if (!CryptDecrypt(hKey, IntPtr.Zero, true, 0, pbBuffer, ref dwCount))
                { return ErrorTypes.CryptDecryptError; }
                //dwCount為解密後長度
 
                NewByte = new byte[dwCount];
                Array.Copy(pbBuffer, 0, NewByte, 0, dwCount);
//若不存檔以下try catch可去除    
                try
                { File.WriteAllBytes(檔名路徑, NewByte); }
                catch
                { return ErrorTypes.FileWriteError; }
            }
            finally
            {
                if (hKey != IntPtr.Zero) CryptDestroyKey(hKey);
                if (hHash != IntPtr.Zero) CryptDestroyHash(hHash); // Destroy hash
                if (hProv != IntPtr.Zero) CryptReleaseContext(hProv, 0); //Release CSP
            }
            return ErrorTypes.NoError;
        }
 
        /// <summary>
        /// 讀取file
        /// </summary>
        /// <param name="Filename"></param>
        /// <returns></returns>
        private static byte[] ReadFile(string Filename)
        {
            byte[] pbBuffer = null;
            try
            { pbBuffer = File.ReadAllBytes(Filename); }
            catch { }
            return pbBuffer;
        }
 
        /// <summary>
        /// 產生key
        /// </summary>
        /// <param name="Filename"></param>
        /// <param name="hKey"></param>
        /// <param name="hProv"></param>
        /// <param name="hHash"></param>
        /// <returns></returns>
        private static ErrorTypes BefCrypt(string Filename, ref IntPtr hKey, ref IntPtr hProv, ref  IntPtr hHash)
        {
            if (!CryptAcquireContext(out hProv, pszContainer, MS_DEF_PROV, PROV_RSA_FULL, 0))
            {
                if (!CryptAcquireContext(out hProv, pszContainer, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
                { return ErrorTypes.CryptAcquireContextError; }
            }
 
            if (!CryptCreateHash(hProv, ALG_ID.CALG_MD5, IntPtr.Zero, 0, out hHash))
            { return ErrorTypes.CryptCreateHashError; }
 
            byte[] fnBuffer =密碼2
            if (!CryptHashData(hHash, fnBuffer, fnBuffer.Length, 0))
            { return ErrorTypes.CryptHashDataError; }
 
            if (!CryptDeriveKey(hProv, ALG_ID.CALG_RC2, hHash, CRYPT_EXPORTABLE, ref hKey))
            { return ErrorTypes.CryptDeriveKeyError; }
 
            return ErrorTypes.NoError;
        }
    }
}

 

Taiwan is a country. 臺灣是我的國家