zoukankan      html  css  js  c++  java
  • DPAPI加密

        // <summary>
        /// Window自带加密解密DPAPI
        /// </summary>
        public class DPAPI
        {
    
            #region
    
            /// <summary>
            /// DPAPI加密
            /// </summary>
            /// <param name="pPlainText"></param>
            /// <param name="szDescription"></param>
            /// <param name="pEntropy"></param>
            /// <param name="pReserved"></param>
            /// <param name="pPrompt"></param>
            /// <param name="dwFlags"></param>
            /// <param name="pCipherText"></param>
            /// <returns></returns>
            [DllImport("crypt32.dll", EntryPoint = "CryptProtectData", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
            public static extern bool DPAPIEncrypt(ref DATA_BLOB pPlainText, string szDescription, ref DATA_BLOB pEntropy, IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pCipherText);
    
            /// <summary>
            /// DPAPI解密
            /// </summary>
            /// <param name="pCipherText"></param>
            /// <param name="pszDescription"></param>
            /// <param name="pEntropy"></param>
            /// <param name="pReserved"></param>
            /// <param name="pPrompt"></param>
            /// <param name="dwFlags"></param>
            /// <param name="pPlainText"></param>
            /// <returns></returns>
            [DllImport("crypt32.dll", EntryPoint = "CryptUnprotectData", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
            public static extern bool DPAPIDecrypt(ref DATA_BLOB pCipherText, ref string pszDescription, ref DATA_BLOB pEntropy, IntPtr pReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPrompt, int dwFlags, ref DATA_BLOB pPlainText);
    
            #endregion
    
            #region
    
            /// <summary>
            /// 密钥类型
            /// </summary>
            public enum KeyType
            {
                /// <summary>
                /// 用户存储
                /// </summary>
                UserKey = 1,
                /// <summary>
                /// 机器存储
                /// </summary>
                MachineKey
            };
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct DATA_BLOB
            {
                public int cbData;
                public IntPtr pbData;
            }
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct CRYPTPROTECT_PROMPTSTRUCT
            {
                public int cbSize;
                public int dwPromptFlags;
                public IntPtr hwndApp;
                public string szPrompt;
            }
    
            private static IntPtr NullPtr = ((IntPtr)((int)(0)));
    
            private static KeyType defaultKeyType = KeyType.UserKey;
    
            private const int CRYPTPROTECT_UI_FORBIDDEN = 0x1;
            private const int CRYPTPROTECT_LOCAL_MACHINE = 0x4;
    
            #endregion
    
            private static void InitPrompt(ref CRYPTPROTECT_PROMPTSTRUCT ps)
            {
                ps.cbSize = Marshal.SizeOf(typeof(CRYPTPROTECT_PROMPTSTRUCT));
                ps.dwPromptFlags = 0;
                ps.hwndApp = NullPtr;
                ps.szPrompt = null;
            }
    
            private static void InitBLOB(byte[] data, ref DATA_BLOB blob)
            {
                blob.pbData = Marshal.AllocHGlobal(data.Length);
                if (blob.pbData == IntPtr.Zero)
                    throw new Exception("无法为BLOB结构分配数据缓冲区");
    
                blob.cbData = data.Length;
                Marshal.Copy(data, 0, blob.pbData, data.Length);
            }
    
            /// <summary>
            /// 加密
            /// </summary>
            /// <param name="plainText">要加密明文</param>
            /// <returns></returns>
            public static string Encrypt(string plainText)
            {
                return Encrypt(defaultKeyType, plainText, String.Empty, String.Empty);
            }
    
            /// <summary>
            /// 加密
            /// </summary>
            /// <param name="keyType">密钥类型</param>
            /// <param name="plainText">要加密明文</param>
            /// <returns></returns>
            public static string Encrypt(KeyType keyType, string plainText)
            {
                return Encrypt(keyType, plainText, String.Empty, String.Empty);
            }
    
            /// <summary>
            /// 加密
            /// </summary>
            /// <param name="keyType">密钥类型</param>
            /// <param name="plainText">要加密明文</param>
            /// <param name="entropy"></param>
            /// <returns></returns>
            public static string Encrypt(KeyType keyType, string plainText, string entropy)
            {
                return Encrypt(keyType, plainText, entropy, String.Empty);
            }
    
            /// <summary>
            /// 加密
            /// </summary>
            /// <param name="keyType">密钥类型</param>
            /// <param name="plainText">要加密明文</param>
            /// <param name="entropy"></param>
            /// <param name="description"></param>
            /// <returns></returns>
            public static string Encrypt(KeyType keyType, string plainText, string entropy, string description)
            {
                if (plainText == null)
                    plainText = String.Empty;
                if (entropy == null)
                    entropy = String.Empty;
    
                return Convert.ToBase64String(Encrypt(keyType, Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(entropy), description));
            }
    
            /// <summary>
            /// 加密
            /// </summary>
            /// <param name="keyType">密钥类型</param>
            /// <param name="plainTextBytes">要加密明文</param>
            /// <param name="entropyBytes"></param>
            /// <param name="description"></param>
            /// <returns></returns>
            public static byte[] Encrypt(KeyType keyType, byte[] plainTextBytes, byte[] entropyBytes, string description)
            {
                if (plainTextBytes == null)
                    plainTextBytes = new byte[0];
                if (entropyBytes == null)
                    entropyBytes = new byte[0];
                if (description == null)
                    description = String.Empty;
    
                DATA_BLOB plainTextBlob = new DATA_BLOB();
                DATA_BLOB cipherTextBlob = new DATA_BLOB();
                DATA_BLOB entropyBlob = new DATA_BLOB();
    
                CRYPTPROTECT_PROMPTSTRUCT prompt = new CRYPTPROTECT_PROMPTSTRUCT();
                InitPrompt(ref prompt);
    
                try
                {
                    try
                    {
                        InitBLOB(plainTextBytes, ref plainTextBlob);//将明文字节转换为BLOB结构。
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("无法初始化纯文本BLOB", ex);
                    }
    
                    try
                    {
                        InitBLOB(entropyBytes, ref entropyBlob);//将熵字节转换为BLOB结构
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("无法初始化熵BLOB。", ex);
                    }
    
                    int flags = CRYPTPROTECT_UI_FORBIDDEN;
                    if (keyType == KeyType.MachineKey)
                        flags |= CRYPTPROTECT_LOCAL_MACHINE;
    
                    bool success = DPAPIEncrypt(ref plainTextBlob, description, ref entropyBlob, IntPtr.Zero, ref prompt, flags, ref cipherTextBlob);
                    if (!success)
                    {
                        throw new Exception("CryptProtectData失败", new Win32Exception(Marshal.GetLastWin32Error()));
                    }
    
                    byte[] cipherTextBytes = new byte[cipherTextBlob.cbData];
                    Marshal.Copy(cipherTextBlob.pbData, cipherTextBytes, 0, cipherTextBlob.cbData);
                    return cipherTextBytes;
                }
                catch (Exception ex)
                {
                    throw new Exception("DPAPI无法加密数据", ex);
                }
                finally
                {
                    if (plainTextBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(plainTextBlob.pbData);
    
                    if (cipherTextBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(cipherTextBlob.pbData);
    
                    if (entropyBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
    
            /// <summary>
            /// 解密
            /// </summary>
            /// <param name="cipherText">要解密的密文</param>
            /// <returns></returns>
            public static string Decrypt(string cipherText)
            {
                string description;
                return Decrypt(cipherText, String.Empty, out description);
            }
    
            /// <summary>
            /// 解密
            /// </summary>
            /// <param name="cipherText">要解密的密文</param>
            /// <param name="description"></param>
            /// <returns></returns>
            public static string Decrypt(string cipherText, out string description)
            {
                return Decrypt(cipherText, String.Empty, out description);
            }
    
            /// <summary>
            /// 解密
            /// </summary>
            /// <param name="cipherText">要解密的密文</param>
            /// <param name="entropy"></param>
            /// <param name="description"></param>
            /// <returns></returns>
            public static string Decrypt(string cipherText, string entropy, out string description)
            {
                if (entropy == null)
                    entropy = String.Empty;
    
                return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(cipherText), Encoding.UTF8.GetBytes(entropy), out description));
            }
    
            /// <summary>
            /// 解密
            /// </summary>
            /// <param name="cipherTextBytes">要解密的密文</param>
            /// <param name="entropyBytes"></param>
            /// <param name="description"></param>
            /// <returns></returns>
            public static byte[] Decrypt(byte[] cipherTextBytes, byte[] entropyBytes, out string description)
            {
                DATA_BLOB plainTextBlob = new DATA_BLOB();
                DATA_BLOB cipherTextBlob = new DATA_BLOB();
                DATA_BLOB entropyBlob = new DATA_BLOB();
    
                CRYPTPROTECT_PROMPTSTRUCT prompt = new CRYPTPROTECT_PROMPTSTRUCT();
                InitPrompt(ref prompt);
                description = String.Empty;
    
                try
                {
                    try
                    {
                        InitBLOB(cipherTextBytes, ref cipherTextBlob);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("无法初始化密文BLOB", ex);
                    }
    
                    try
                    {
                        InitBLOB(entropyBytes, ref entropyBlob);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("无法初始化熵BLOB", ex);
                    }
    
                    int flags = CRYPTPROTECT_UI_FORBIDDEN;
                    bool success = DPAPIDecrypt(ref cipherTextBlob, ref description, ref entropyBlob, IntPtr.Zero, ref prompt, flags, ref plainTextBlob);
                    if (!success)
                    {
                        throw new Exception("CryptUnprotectData失败", new Win32Exception(Marshal.GetLastWin32Error()));
                    }
    
                    byte[] plainTextBytes = new byte[plainTextBlob.cbData];
                    Marshal.Copy(plainTextBlob.pbData, plainTextBytes, 0, plainTextBlob.cbData);
                    return plainTextBytes;
                }
                catch (Exception ex)
                {
                    throw new Exception("DPAPI无法解密数据", ex);
                }
                finally
                {
                    if (plainTextBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(plainTextBlob.pbData);
    
                    if (cipherTextBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(cipherTextBlob.pbData);
    
                    if (entropyBlob.pbData != IntPtr.Zero)
                        Marshal.FreeHGlobal(entropyBlob.pbData);
                }
            }
    
        }
  • 相关阅读:
    testng遇到的一些问题
    Redis-常用命令总结
    Spring AOP
    Spring IOC
    Java-J.U.C总结
    Java-将map拼接成“参数=值&参数=值”
    java多线程-线程池
    mysql 二进制文件增量备份
    Centos下mysql数据库备份与恢复的方法
    CentOS下mysql默认安装位置
  • 原文地址:https://www.cnblogs.com/tlmbem/p/10800660.html
Copyright © 2011-2022 走看看