aes加密解密与sqlserver 实现加密解密

alexlee 2024-8-9 114 8/9

最近项目上出现了明文密码,被检测出来漏洞了,那也就是说,我们的密码要加密,这本身就是一件非常平常的事情。

这里大家或是有经验的开发人员,可能觉得再普通不过了,直接md5加密,跟数据库的字段做匹配,一致的就可以登录成功了。

要是这么简单的话,就不用特意来记录这个安全了,我们项目是这样的,这个项目用上了AD域登录,不知道大家对这个有没有什么概念。

接下来是AD域的概念:

“域帐号登录”属于“交互式登录”(即用户通过相应的用户帐号(UserAccount)和密码进行登录)的一种(另外一种为“本地登录”)。采用域用户帐号登录计算机,系统通过存储在域控制器的活动目录中的数据进行验证。如果该用户帐号有效,则登录后可以访问到整个域中具有访问权限的资源。

其实大概就是这么个意思,就是客户不想用户每个系统一个密码,这样用户太麻烦了,所以都统一使用AD域的密码账户来登录各个业务系统。

那介绍了AD的概念之后,究竟跟我们的密码加密有什么有关系呢?主要是AD域这里使用的是明文密码,所以我们不能用MD5加密,否则肯定验证不成功的。

为此,我们这里就引进了一种AES对称式加密,对密码进行解密,最后再传到AD域那边去验证,让业务系统整个流程可以跑通起来。

那接下来,我们就要介绍下,我们的AES算法了

接下来用的是C#的代码

//加密

publicstaticstringEncrypt(stringstr,stringstrkey,stringstrvalue)

{

//byte[]IV={57,87,122,110,97,109,111,53,65,95,114,101,120,73,72,84};

//stringkey="MKE7612Y4ADF8JD1";

byte[]clearBytes=Encoding。UTF8。GetBytes(str);

byte[]keyBytes=Encoding。UTF8。GetBytes(strkey);

byte[]ivBytes=Encoding。UTF8。GetBytes(strvalue);

//byte[]clearBytes=Convert。FromBase64String(str);

using(Aesencryptor=Aes。Create())

{

encryptor。Key=keyBytes;

encryptor。IV=ivBytes;

using(MemoryStreamms=newMemoryStream())

{

using(CryptoStreamcs=newCryptoStream(ms,encryptor。CreateEncryptor(),CryptoStreamMode。Write))

{

cs。Write(clearBytes,0,clearBytes。Length);

cs。Close();

}

str=Convert。ToBase64String(ms。ToArray());

}

}

returnstr;

}

publicstaticstringDecryptStringAES(stringencryptedValue,stringstrkey,stringstrvalue)

{

try

{

varkeybytes=Encoding。UTF8。GetBytes(strkey);

variv=Encoding。UTF8。GetBytes(strvalue);

//DECRYPTFROMCRIPTOJS

varencrypted=Convert。FromBase64String(encryptedValue);

vardecriptedFromJavascript=DecryptStringFromBytes(encrypted,keybytes,iv);

returndecriptedFromJavascript;

}

catch(Exceptionex)

{

return"";

}

}

//解密

privatestaticstringDecryptStringFromBytes(byte[]cipherText,byte[]key,byte[]iv)

{

//Checkarguments。

if(cipherText==null||cipherText。Length<=0)

{

thrownewArgumentNullException("cipherText");

}

if(key==null||key。Length<=0)

{

thrownewArgumentNullException("key");

}

if(iv==null||iv。Length<=0)

{

thrownewArgumentNullException("key");

}

//Declarethestringusedtohold

//thedecryptedtext。

stringplaintext=null;

//CreateanRijndaelManagedobject

//withthespecifiedkeyandIV。

using(varrijAlg=newRijndaelManaged())

{

//Settings

rijAlg。Mode=CipherMode。CBC;

rijAlg。Padding=PaddingMode。PKCS7;

rijAlg。FeedbackSize=128;

rijAlg。Key=key;

rijAlg。IV=iv;

//Createadecrytortoperformthestreamtransform。

vardecryptor=rijAlg。CreateDecryptor(rijAlg。Key,rijAlg。IV);

//Createthestreamsusedfordecryption。

using(varmsDecrypt=newMemoryStream(cipherText))

{

using(varcsDecrypt=newCryptoStream(msDecrypt,decryptor,CryptoStreamMode。Read))

{

using(varsrDecrypt=newStreamReader(csDecrypt))

{

//Readthedecryptedbytesfromthedecryptingstream

//andplacetheminastring。

plaintext=srDecrypt。ReadToEnd();

}

}

}

}

returnplaintext;

}

调用语句加密

stringaa=aesenHelper。Encrypt("123","2023080514454401","2023080514454401");

通过代码,大家以为到这里就完了,其实不然,那假如,我们在数据库里边要进行加密解密怎么办?

这里研究了很久,反正我没找到可以直接用sql把C#的代码还原到sqlserver数据库里边。试过很多种方法,都没办法加密出一样的密文,为此,我们使用了 clr这种功能。

以下是sqlserver代码

--开启CLR支持,并且指定某个数据库支持unsafe模式

EXECsp_configure'clrenabled',1;

RECONFIGURE;

GO

ALTERDATABASEv3_kd_newSETTRUSTWORTHYON;

GO

Sp_changedbowner'sa',true--sa

--为了能够调到C#的Encrypt方法,需要SQLSERVER先导入这个程序集,然后再以Function映射其中方法即可

--dropASSEMBLYclr_Bussiness

CREATEASSEMBLYclr_Bussiness

FROM'E:\database\aesencryption。dll'

WITHPERMISSION_SET=UNSAFE;

GO

--dropfunction clr_Encrypt

CREATEFUNCTIONdbo。clr_Encrypt

(

@strASNVARCHAR(100),

@strkeyASNVARCHAR(100),

@strvalueASNVARCHAR(100)

)

RETURNSNVARCHAR(100)

AS

EXTERNALNAMEclr_Bussiness。[aesencryption。aesenHelper]。Encrypt;

GO

--创建完了之后,可以观察assembly开头的几个系统视图

SELECT*FROMsys。assemblieswherename='clr_Bussiness'

SELECT*FROMsys。assembly_files;

SELECT*FROMsys。assembly_modules;

--接下来调用一下刚才创建的clr_UserLogin函数。

selectdbo。clr_Encrypt(N'123',N'2023080514454401',N'2023080514454401')AS'aa'

以上是自己的做为资深开发的一些个人经历,把这些经验分享给大家,希望以后大家在从事开发中,可以避免不必要的麻烦,跟浪费时间精力。

要是大家喜欢我的文章的话,可以在文章下留言或是联系我,共同进步,共同探讨开发的一些案例,促进彼此间的交流,分享一些日常的开发趣事。

 

- THE END -
最后修改:2024年8月9日
0

共有 0 条评论