VB 实现中文文本的加密方法

前端之家收集整理的这篇文章主要介绍了VB 实现中文文本的加密方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

VB文本加密 特别设计到中文加密 让很多人费尽周折,经常会碰到解密中文出现乱码的情况

下面这篇文章将对此做了说明

代码也在文章里面包括

计算机世界2000年第36期

实现中文文本的加密方法

武汉交通科技大学计算机科学与工程系 吴业福

  

本文介绍了在VB6中实现中、英文文本加、解密的技术细节。文中深入地探讨了VB6中汉字加、解密的原理、散列函数的构造方案,在加、解密方产生散列函数的种子值(初始值)和用于加、解密的随机序列数的方法。最后该技术实现了一个简单的128位的加、解密方案。文中涉及到了加密技术的一些主要关键概念及其具体实现技术,如散列函数、加密强度等。 

绪 论

  加密(Encryption)是信息保护的一种必不可少的手段。目前有两种基本的加密方法,即私钥加密和公钥加密。用VB既可用自定义算法实现简便的私钥加密,也可通过调用Crypto API接口实现复杂的公钥加密。

  本文介绍一种私钥加密技术,不仅能加密英文文本,而且能有效加密汉字。

  密文文本=HASH(DateTime)+HASH(DateTime+Key)+ Encryption(Text,HASH(DateTime)+HASH(DateTime+Key)

   VB具体实现技术

  1. 基本加解密函数(XOR)

  在VB中提供了一个XOR函数,它既可对字符也可对数字、布尔变量进行异或,两次异或的结果即为原值。因此,它是基本加解密函数

  例如:Ascw(“息”)XOR 28值为24943,24943 XOR 28值为24687,Chrw(24687) 值为“息”。

  2.汉字的加密与解密方法

  在VB中,字符的处理相当复杂,特别是汉字和英文字符混合处理,其结果更是无法预料。在VB内部,字符全部作为Unicode处理,并且VB支持三种类型的字符集,并提供了相应的字符处理函数

  VB支持的三种类型字符集是:

  ⑴ ANSI:一个字节表示一个字符,汉字被作为两个 ANSI字符;

  ⑵ DBCS:双字节字符集,0~128表示ASCII字符, ASCII字符长度为1个字节,汉字等东亚字符的长度为2个字节,汉字被作为一个DBCS字符;

  ⑶ Unicode:用两个字节表示每个字符。ISO几乎为每种语言的每个字符和符号在0~65,535(216-1)范围定义了一个数字,汉字被作为一个Unicode字符。

  在VB6中,字符串的处理函数有ANSI/DBCS版本、二进制版本和Unicode版本。因此,对于汉字的处理相当复杂。

  例如:Asc(返回第一个字符的ANSI/DBCS字符代码);
  AscB(返回第一个字节的值);
  AscW(返回第一个Unicode字符之代码)。

  例如:Asc(“息”)之值为:-12382,Chr(-12382)之值为:息,AscW(“息”)之值为:24687,Chrw(24687)之值为:息。

  经过反复实验证实,使用Unicode字符集及Unicode字符集函数可较好地加密汉字。

  本加解密方案中,汉字和英文字符的加解密均使用下列函数

  • AscW( ):返回第一个Unicode字符之代码,每个英文和汉字均作为一个字符,其长度为1;
  • Mid( ) :取子串,每个英文和汉字均作为一个字符;
  • ChrW( ) :返回该代码所对应的Unicode字符,字符为英文或汉字;
  • Len( ) 函数:返回字符串的长度,每个英文字符和汉字字符的长度均为1。

  其使用方法请见自定义函数Doxor( )中的语句: Public Sub DoXor(ByRef msFileText as String) ‘本函数用于对msFileText中的字符串进行XOR 27操作, 英文或汉字均作为一个字符来处理, ‘加密方调用该模块用于加密,解密方调用该模块用于解密。 ‘使用Unicode函数AscW 、ChrW可正确处理所有汉字 ‘使用ASC函数Asc 、Chr无法正确处理所有汉字 Dim intC As Integer Dim intB As Integer Dim lngI As Long ‘下面,用Rnd产生随机序列数, 然后根据Int(Rnd * 2 ^ 7)得到一个对应整数, ‘再用该整数与msFileText中字符XOR。 For lngI = 1 To Len(msFileText) intC = AscW(Mid(msFileText,lngI,1)) intB = Int(Rnd * 2 ^ 7) ‘选用<=127可正确处理汉字,ChrW(n):n 有一个范围 Mid(msFileText,1) = ChrW(intC Xor intB) Next lngI End Sub

  在对包含有汉字的文本(明文、密文)文件(.txt)进行读、写处理时,也要考虑汉字的问题,主要是长度问题,用不同的语句/函数,读出的结果不一样,有的超出实际长度。具体处理办法是:使用ASCII格式:

  1读明文、读密文: Open FileOldName For Binary As #1 sHead = Input(LOF(1),#1) Close #1

  注意:不能用下述方法,因为它将汉字作为两个字符处理,导致读出的sHead超出实际长度(超出长度=汉字个数): Open FileOldName For Binary As #1 sHead = Space(LOF(1)) Input #1,sHead Get #1,sHead Close #1

  2写密文、写明文: Open FileNewName For Binary As #1 ‘存为AscwII格式 Put #1,ET Close #1

  3.散列函数(HASH函数

  散列函数(也叫哈希函数)是密码学和数学中的一个概念。其作用是能够基于给定的输入字串、文件或其他类型二进制数据产生一个独一无二值。此外,该函数采用的算法能够保证人们不能从它反向推得该值的原始信息。

  对于Hash函数,其初始值(种子值)的选择至关重要。为了保证产生和检查散列代码的双方使用相同的初始值,可以选择固定的伪随机初始值。

  在VB中提供了一个返回随机数值的函数Rnd( ),以及初始化随机生成器的Randomize( ):

  • Rnd函数格式:Rnd[(number)]。若number<0,每次都使用number作为随机数种子得到的相同结果。
  • Randomize函数格式:Randomize[(number)]。Randomize用number将Rnd函数随机生成器初始化。该随机生成器给number一个新的种子值。若省略,则用系统记时器返回的值作为新的种子值。若想得到重复的随机数序列,在使用具有数值参数的Randomize之前直接调用具有负参数值Rnd函数

  本加解密方案中为保证发送方(加密方)和接收方(解密方)得到相同的随机种子值,在HASH函数调用DOXOR之前初始化种子值(过程名为 initialize): Private Sub Initialize(vKeyString As String) Dim intI As Integer,intJ As Integer Randomize Rnd(-1) ‘得到初始值(种子值),每次调用初始值均相同 ‘根据初始值(种子值)得到随机数序列, 每次调用Initialize时,初始值均相同。 只要vKeyString相同,所产生的随机数序列一定相同 For intI = 1 To Len(vKeyString) intJ = Rnd(-Rnd * AscW(Mid(vKeyString,intI,1))) Randomize intJ Next intI End Sub

  有了上面的知识,就可以设计HASH函数。本加密解密方案中HASH函数如下: Public Function Hash(ET As String) As String Dim BitLenString as String, KeyString as String,FileText as String BitLenString= “12345678" KeyString = ET & BitLenString Call Initialize(KeyString) ‘根据KeyString产生随机数序列 FileText = ET & BitLenString Call DoXor(FileText) ‘根据上述随机数序列对FileText加密 KeyString = FileText Call Initialize(KeyString) ‘根据上述的加密结果产生新的随机数序列 FileText = BitLenString Call DoXor(FileText) ‘根据上述随机数序列对FileText加密,8位字符 Hash = FileText ‘8位字符送作HASH值 End Function

  4.加密过程实现 Public Sub Encrypt() Dim sHead As String,DH As String,ET As String,n As Long,, KeyString as String,FileText as String Dim PasswordChar FileOldName As String,FileNewName As String PasswordChar = InputBox(“加密口令:") FileOldName = InputBox(“明文文件名(.txt):") FileNewName = InputBox(“存放密文文件名(.txt):") Open FileOldName For Binary As #1 ‘FileOldName必须为ascwII格式 ET = Input(LOF(1),#1) Close #1 DH = Hash(Date & Str(Timer)) ‘加时间戳 sHead =“[Secret]"&DH &Hash (DH & PasswordChar) ‘产生明文的加密密钥,8+8+8位字符 KeyString = sHead Call Initialize(KeyString) ‘根据明文的加密密钥产生随机数序列 FileText = ET DoXor(FileText) ‘根据上述随机数序列对明文加密 ET = FileText Open FileNewName For Binary As #1 ‘存为ascwII格式 Put #1,sHead + ET Close #1 MsgBox (“加密完成!") End Sub

  5.解密过程实现 Public Sub Decrypt() Dim sHead As String, KeyString as String,FileText as String Dim DH As String,TH As String,n As Long Dim PasswordChar FileOldName As String,FileNewName As String PasswordChar = InputBox(“解密口令:") FileOldName = InputBox(“密文文件名(.txt):") FileNewName = InputBox(“存放明文文件名(.txt):") Open FileOldName For Binary As #1 sHead = Input(LOF(1),#1) Close #1 DH =Mid(sHead,9,8) ‘得到DH ET= Mid(sHead,25,Len(sHead) - 24) ‘得到密文 sHead =Mid(sHead,1,24) ‘得到解密密钥 If InStr(sHead,Hash(DH & PasswordChar)) <> 17 Then ‘口令鉴别 MsgBox (“口令不正确!") Exit Sub End If KeyString = sHead Call Initialize(KeyString) ‘用8+8+8位解密密钥产生解密随机数序列, FileText = ET DoXor(FileText) ‘根据上述随机数序列解密 ET= FileText ‘明文存入ET Open FileNewName For Binary As #1 ‘存为ascwII格式 Put #1,ET Close #1 MsgBox (“解密完成!") End Sub 加密位数的探讨

  本加解密方案的加密强度为8+8+8=24位。若要实现更多位的加密,对本方案稍加修改也可以。若要实现128位的加密强度,则可修改HASH 函数如下:BitLenString=任意128位字符。

  例如:BitLenString= “ ABCDEFGHIJKLMNOPQRSTUVWXYZ1234", 则加密位数为 30*3=90位。 小 结

  本加解密方案的最大特点之一是并未用用户口令直接去加密明文,而是将私钥进行HASH的映射(实现上也是加密)后,再与随机数序列等其他信息一起构成特定位数的加密字符串,去加密明文,使得加密强度与用户口令密码长度无关,并且加密方法更安全。

  本加解密方案的另一大特点是加密时使用了时间标志,所以每次加密后的密文都不一样。

  将本加密程序生成Active X DLL/EXE部件可直接在 Windows下的其他系统中运行。

猜你在找的VB相关文章