无论c#加密还是sql语句加密,sql和c#都可以解秘,实现方法是采用数字证书方法.实现加密传输
感谢本文章作者
http://www.itstrike.cn/Question/acdd965a-c6d9-43ce-ad0d-af1484455671.html
感谢一个英文翻译后让中国人和外国人都看不懂的百度翻译.
我将该文章的方法及遇到的问题,做一个详细说明,本人技术有限,有错误的地方欢迎指正,废话不多说,进入正题.
因业务需要,c#对字符串加密后存入数据库,sql语句(sql2008数据库)需要解密.我选择使用数字证书加密,数字证书采用RSA加密算法进行加密,有公钥和私钥,公钥加密,私钥解密

一:创建自己的数字证书

(也可以购买被认可的数字证书)

需要使用的软件makecert.exe和pvk2pfx.exe(百度一搜一大片)

pysqlcipher3加密sqlite3数据库 sql加密语句_中国


打开windows命令处理程序(dos命令)

C:\Users>j:

进入存放软件的目录下

然后运行一下命令”makecert -sv PrivateKey.pvk -n “cn=TestCertificate” TestCertificate.cer -b 01/01/2013 -e 01/01/2024 -sky Exchange”创建一个证书,生成的证书位置和你软件的位置一样

J:>makecert -sv PrivateKey.pvk -n “cn=TestCertificate” TestCertificate.cer -b 01/01/2013 -e 01/01/2024 -sky Exchange

注意:如果提示makecert不是内部或外部命令,也不是可运行的程序或批处理文件,遇到这种问题请用”管理员身份”打开dos,如果还是报错请查看该目录下软件名是否正确

pysqlcipher3加密sqlite3数据库 sql加密语句_加密_02


选择”无”

pysqlcipher3加密sqlite3数据库 sql加密语句_加密_03


出现succeeded代表创建成功以上创建两个文件PrivateKey.pvk(这个是私钥文件)和TestCertificate.cer(数字证书文件),这两个文件需要数据库使用

dos命令输入”pvk2pfx -pvk PrivateKey.pvk -spc TestCertificate.cer -po TestEncryption123”

这个命令是创建pfx文件,这个文件是c#程序使用的,加密解密都需要这个文件

pysqlcipher3加密sqlite3数据库 sql加密语句_技术_04


pysqlcipher3加密sqlite3数据库 sql加密语句_加密_05


点击”下一步”

pysqlcipher3加密sqlite3数据库 sql加密语句_加密_06


选择”是,导出私钥”,点击”下一步”

pysqlcipher3加密sqlite3数据库 sql加密语句_加密_07


选择

• 如果可能,将所有证书都包括证书路径中

• 导出所有的 extendend 属性

点击”下一步”

pysqlcipher3加密sqlite3数据库 sql加密语句_中国_08


设置密码,这个密码在代码打开数字证书时使用,下一步

pysqlcipher3加密sqlite3数据库 sql加密语句_加密_09


下一步

pysqlcipher3加密sqlite3数据库 sql加密语句_技术_10


完成

pysqlcipher3加密sqlite3数据库 sql加密语句_中国_11


现在创建成功

pysqlcipher3加密sqlite3数据库 sql加密语句_百度_12


下面打开数据库

USE master 
 GO 
 –创建数据库 
 CREATE DATABASE TestEncryptionDecryption 
 GO
USE TestEncryptionDecryption 
 –创建表 
 CREATE TABLE Encrypt 
 ( 
 intCol int, 
 clearTextCol varchar(128) 
 ) 
 GO 
 –向表里插入数据 
 INSERT INTO Encrypt (intCol, clearTextCol) 
 VALUES 
 (‘1’, ‘Links’), 
 (‘2’, ‘Zwo’), 
 (‘3’, ‘Drei’), 
 (‘4’, ‘Vier’), 
 (‘5’, ‘Fünf’), 
 (‘6’, ‘5ech5’) 
 GO


–导入证书,这个证书就是上面创建的TestCertificate.cer和PrivateKey.pvk文件

CREATE CERTIFICATE TestCertificate 
 FROM FILE = ‘C:\temp\createCert\TestCertificate.cer’ 
 WITH PRIVATE KEY ( 
 FILE = ‘C:\temp\createCert\PrivateKey.pvk’, 
 –ENCRYPTION BY PASSWORD = ‘TestEncryption123’


–以上语句是设置私钥密码,如果通过数据库解密就需要提供该密码
,加密不需要,现在不需要设置
)
GO

–查看证书是否添加成功

SELECT * FROM sys.certificates


–将clearTextCol列内的数值通过数据库加密后放入encryptedCol里

UPDATE Encrypt 
 SET 
 encryptedCol = ENCRYPTBYCERT 
 ( 
 CERT_ID(‘TestCertificate’), 
 clearTextCol 
 ) 
 GO

–通过sql语句解密刚才加密的列

–DECLARE @Passwd nvarchar(128) = ‘TestEncryption123’


–因为前面没有设置密码,所以现在也不用提供密码

SELECT intCol, 
 clearTextCol, 
 encryptedCol, 
 CAST 
 ( 
 DECRYPTBYCERT 
 ( 
 CERT_ID(‘TestCertificate’), 
 encryptedCol, 
 – @Passwd 
 ) AS varchar(128) 
 ) AS decryptedCol 
 FROM dbo.EncryptGO

pysqlcipher3加密sqlite3数据库 sql加密语句_sql_13


如果出现这种界面代表数据库加解密成功,相同的字符串,每次加密后的值(encryptedCol列)不会相同

注意:导入证书报” 证书、非对称密钥或私钥文件不存在或格式无效。”错误,

出错原因

一: 请查看路径名是否正确,文件名是否正确

二:

pysqlcipher3加密sqlite3数据库 sql加密语句_中国_14


(mycertificate.cer是数据库创建的数字证书, TestCertificate.cer是我创建的证书)

比较两个证书的”组或用户名”发现缺少OWNER和SQL..这两个用户名

请将TestCertificate.cer的文件添加这两个用户. 权限设置”完全控制”

Pvk一样也需要添加这两个用户,并且权限设置”完全控制”

C#源代码
解密方法:

// pfxFilePath—传入pfx存放在电脑的位置 
 // password—-传入用dos创建pfx时设置的密码 
 // EncryptedDocID—传入从数据库取出的加密过的数据 
 public string jiemi(string pfxFilePath, string password, byte[] EncryptedDocID) 
 {
System.Security.SecureString securePassword = new System.Security.SecureString();

        foreach (char keyChar in password.ToCharArray())
            securePassword.AppendChar(keyChar);

//反转一维 Array 或部分 Array 中元素的顺序,
//获取的数据库的字段必须反转元素,c#才能通过证书解密,不反转,提示传入的值无效
//c#加密的后的元素也必须反转,才能被sql语句解密,否则解密失败
Array.Reverse(EncryptedDocID);

string DecryptedDocID = "";

        //load certificate from filesystem and open it with provided password
//实例化证书 
 X509Certificate2 cert = new X509Certificate2(pfxFilePath, password); 
 //判断证书是否打开成功 
 if (cert == null) 
 { 
 throw new Exception(“Certificate ” + pfxFilePath + ” Does not exist”); 
 } 
 //获取私钥,证书是非对称RSA算法加密的,私钥解密,公钥加密,这里获取私钥进//行解密, 
 if (cert.HasPrivateKey) 
 { 
 RSACryptoServiceProvider RsaCSP = (RSACryptoServiceProvider)cert.PrivateKey;//通过Decrypt解密, 
 //Decrypt第二个参数含义,如果为 true,则使用 OAEP 填充(仅可用于运行 Microsoft //Windows XP 及更高版本的计//算机)执行直接 RSA 解密;否则,如果为 false则使用 PKCS#1 v1.5 填充。 
 byte[] ret = RsaCSP.Decrypt(EncryptedDocID, false); 
 if (ret == null) 
 { 
 throw new Exception(“Decryption with RSA failed”); 
 } 
 //进行转码,需要用什么编码格式请查看下面加密方法相同的字段注释 
 DecryptedDocID = Encoding.GetEncoding(“GBK”).GetString(ret); 
 } 
 else 
 { 
 throw new Exception(“Certificate ” + pfxFilePath + ” has no Private Key; “); 
 } 
 return DecryptedDocID; 
 }

加密方法

// pfxFilePath—传入pfx存放在电脑的位置 
 // password—-传入用dos创建pfx时设置的密码 
 // StringMessage—需要加密的字符串public byte[] jiami(string pfxFilePath, string password, string StringMessage) 
 { 
 X509Certificate2 cert = new X509Certificate2(pfxFilePath, password); 
 if (cert == null) 
 { 
 throw new Exception(“Certificate ” + pfxFilePath + ” Does not exist”); 
 } 
 RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
 byte[] BytesMessage = Encoding.GetEncoding(“GBK”).GetBytes(StringMessage); 
 //转码 
 //获取公钥,公钥加密,私钥解密, 数据库就是通过私钥解密,所以这里需要获取公钥进行加密, 
 string keyPublic = cert.PublicKey.Key.ToXmlString(false); 
 provider.FromXmlString(keyPublic); 
 //加密方法 
 byte[] by = provider.Encrypt(BytesMessage, false); 
 //反转一维 Array 或部分 Array 中元素的顺序,这个无论加密解密必须得有否则失败 
 Array.Reverse(by); 
 return by; 
 }

注:如何判断Encoding.GetEncoding(“”)方法使用什么字符

pysqlcipher3加密sqlite3数据库 sql加密语句_sql_15


数据库执行” SELECT COLLATIONPROPERTY(‘Chinese_PRC_Stroke_CI_AI_KS_WS’, ‘CodePage’)” 对应返回的数值就可得出数据库默认的编码方式,我的电脑返回936所以是GBK编码,所以ncoding.GetEncoding()设置GBK

下面是查询结果:

936 简体中文GBK

950 繁体中文BIG5

437 美国/加拿大英语

932 日文

949 韩文

866 俄文

65001 unicode UFT-8