|
-
Nov 16th, 2000, 01:22 PM
#3
Guru
The Crypto API is a set of functions in AdvAPI32.dll, which can encrypt and decrypt using the encryption methods installed.
In my opinion, it's better to code your own.
There are a lot of different encryption algorithms. What you want is probably something that executes mathematical/bitwise operations on the ASCII characters in your String, and to decrypt, the opposite operations are executed.
A good example of an algorithm which works this way is Base64. It is a very commonly used algorithm. In fact, next time you receive an E-mail with a file attachment, look at the details, and you will probably see something like "Encoding: Base64" in there.
Here is how Base64 works:
You have a String that you want to encrypt with Base64. Lets say it is: "Testing!"
Base64 looks at the first three characters.
They are: "Tes"
The ASCII codes are: 84, 101, 115
The ASCII codes in binary: 84 = 1010100b, 101 = 1100101b, 115 = 1110011b.
Now, lets write those binary codes with 8 digits each (put zeroes on the left to make it 8 digits):
01010100 01100101 01110011 (84, 101, 115)
Without spaces:
010101000110010101110011
Now, lets put a space after every 6 digits.
010101 000110 010101 110011
All right so far? We took three numbers and turned them into four, by "changing the spacing".
Now, lets convert those numbers back from binary to decimal:
10101b = 21, 110b = 6, 10101b = 21, 110011b = 51
So, our four numbers are 21, 6, 21, 51.
How to turn those numbers into characters?
For this, we use the Base64 lookup table.
Code:
Const Base64Symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Each number specifies a location in the lookup table where the character is. This is zero based. If the number is 0, the character is "A". If the number is 1, the character is "B". And so on.
We have the numbers 21, 6, 21, 51.
The result is: "VGVz"
So, Base64 changed the String "Tes" to the string "VGVz".
Next three characters in the String "Testing!" are "tin".
This is simple.
"t" = 116, "i" = 105, "n" = 110
116 = 1110100b, 105 = 1101001b, 110 = 1101110b
01110100 01101001 01101110
011101000110100101101110
011101 000110 100101 101110
11101b = 29, 110b = 6, 100101b = 37, 101110b = 46
29 = "d", 6 = "G", 37 = "l", 46 = "u"
"tin" => "dGlu"
Ok so far?
Now, the sort-of-hard part... The next characters are "g!".
We don't have a third character - just two.
This is what we do in this case:
Start as usual...
"g" = 103, "!" = 33
103 = 1100111b, 33 = 100001b
Now, to continue, we keep in mind (actually, in memory) that we started with just two characters... Then we continue as if the third number is 0.
01100111 00100001 00000000
011001110010000100000000
011001 110010 000100 000000
11001b = 25, 110010b = 50, 100b = 4, 0b = 0
25 = "Z", 50 = "y", 4 = "E", 0 = "A"
"g!" & vbNullChar => "ZyEA"
But, this is a mistake. It would be correct if there was a vbNullChar. But since there wasn't, and we remembered that we started with one character "missing", then on the last Base64 symbol, we use "=".
The result is: "g!" => "ZyE="
The all-over result is: "Testing!" => "VGVzdGluZyE="
Now, lets see the String "Testing".
The first parts "Tes" and "tin" are exactly the same, and the results are "VGVz" and "dGlu".
Now, the "g".
"g" = 103
103 = 1100111b
Keep in mind that there were two missing characters, and use zero for the next two numbers.
01100111 00000000 00000000
011001110000000000000000
011001 110000 000000 000000
11001b = 25, 110000b = 48, 0b = 0, 0b = 0
25 = "Z", 48 = "w", 0 = "A", 0 = "A"
"g" & vbNullChar & vbNullChar => "ZwAA"
Again, since there were no null chars, we use "=" for each missing character:
"g" => "Zw=="
And the result over all:
"Testing" => "VGVzdGluZw=="
Here is my implementation of this algorithm in VB (copy and paste to a module):
Code:
Option Explicit
' Base64 encoding:
' An encoded string contains only characters from the Base64Symbols constant below.
' According to an ANSI standard, these characters are sent faster.
' This is often used for encoding files as E-mail attachments.
Private Const Base64Symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
' Function created because I don't have VB6, so I have no Replace:
Private Function RemoveFromString(ByVal TheString As String, ByVal WhatToRemove As String) As String
Dim lPos As Long
If Len(WhatToRemove) = 0 Then Exit Function
Do
lPos = InStr(TheString, WhatToRemove)
If lPos = 0 Then Exit Do
TheString = Left(TheString, lPos - 1) & Mid(TheString, lPos + Len(WhatToRemove))
Loop
RemoveFromString = TheString
End Function
' Base64Encode(sMessage [, nBreak])
' sMessage is the message to encrypt.
' nBreak is how much to break the result (0 means no breaking needed)
' For example, if the result is "ABCDEFGHIJ==" and nBreak = 5, this is returned:
' ABCDE<CrLf>FGHIJ<CrLf>==
' (Instead of <CrLf>, vbCrLf is used)
Function Base64Encode(ByVal sMessage As String, Optional ByVal nBreak As Long = 0) As String
Dim btByte As Byte
Dim I As Long, nLength As Long
nLength = Len(sMessage)
Select Case nLength
Case 0
' Return an empty string.
Case 1 To 3
' Encoding up to 3 characters:
sMessage = sMessage & String(3 - nLength, vbNullChar)
' First Base64 "digit":
btByte = Asc(Left(sMessage, 1)) \ &H4
Base64Encode = Mid(Base64Symbols, btByte + 1, 1)
' Second Base64 "digit":
btByte = ((Asc(Left(sMessage, 1)) And &H3) * &H10) Or (Asc(Mid(sMessage, 2, 1)) \ &H10)
Base64Encode = Base64Encode & Mid(Base64Symbols, btByte + 1, 1)
' Third Base64 "digit":
btByte = ((Asc(Mid(sMessage, 2, 1)) And &HF) * 4) Or _
((Asc(Mid(sMessage, 3, 1)) And &HC0) \ &H40)
Base64Encode = Base64Encode & Mid(Base64Symbols, btByte + 1, 1)
' Fourth Base64 "digit":
btByte = Asc(Mid(sMessage, 3, 1)) And &H3F
Base64Encode = Base64Encode & Mid(Base64Symbols, btByte + 1, 1)
' "=" symbols for shorter strings:
If nLength = 1 Then Mid(Base64Encode, 3, 2) = "=="
If nLength = 2 Then Mid(Base64Encode, 4, 1) = "="
Case Else
' Encoding more than 3 characters:
' Use Base64Encode recursively to encode 3 characters at a time.
For I = 1 To nLength Step 3
Base64Encode = Base64Encode & Base64Encode(Mid(sMessage, I, 3))
Next
End Select
' Is breaking needed?
If nBreak = 0 Then Exit Function
' Yes:
I = nBreak + 1 ' First break.
While I < Len(Base64Encode)
' Add a break:
Base64Encode = Left(Base64Encode, I - 1) & vbCrLf & Mid(Base64Encode, I)
' Increment I:
I = I + nBreak + 2 ' 2 = Len(vbCrLf)
Wend
End Function
' Base64Decode(sMessage)
' sMessage is the Base64 message to decrypt.
Function Base64Decode(ByVal sMessage As String) As String
Dim btByte As Byte
Dim I As Long, lPos As Long
' Remove all unneeded characters:
For I = 0 To 255
' Allowed: Anything in Base64Symbols, and "=".
If (InStr(Base64Symbols, Chr(I)) = 0) And (Not I = Asc("=")) Then _
sMessage = RemoveFromString(sMessage, Chr(I))
Next
' There must be something in the string:
If sMessage = vbNullString Then Exit Function
' Size of string must be divisible by 4:
If Not Len(sMessage) Mod 4 = 0 Then Exit Function
' "=" can only appear in the last two bytes of the string:
Do
lPos = InStr(lPos + 1, sMessage, "=")
If lPos = 0 Then Exit Do
If lPos < Len(sMessage) - 1 Then Exit Function
Loop
' If it's just four bytes, take care of them.
' If it's more, use this function recursively.
If Len(sMessage) = 4 Then
' First byte, from "digits" 1 and 2:
btByte = ((InStr(Base64Symbols, Left(sMessage, 1)) - 1) * &H4) Or _
((InStr(Base64Symbols, Mid(sMessage, 2, 1)) - 1) \ &H10)
Base64Decode = Chr(btByte)
' Second byte, from "digits" 2 and 3:
If Not Mid(sMessage, 3, 1) = "=" Then
btByte = (((InStr(Base64Symbols, Mid(sMessage, 2, 1)) - 1) And &HF) * &H10) Or _
(((InStr(Base64Symbols, Mid(sMessage, 3, 1)) - 1) And &H3C) \ &H4)
Base64Decode = Base64Decode & Chr(btByte)
End If
' Third byte, from "digits" 3 and 4:
If Not Mid(sMessage, 4, 1) = "=" Then
btByte = (((InStr(Base64Symbols, Mid(sMessage, 3, 1)) - 1) And &H3) * &H40) Or _
(InStr(Base64Symbols, Mid(sMessage, 4, 1)) - 1)
Base64Decode = Base64Decode & Chr(btByte)
End If
Else
' Use recursively, 4 "digits" at a time:
For I = 1 To Len(sMessage) Step 4
Base64Decode = Base64Decode & Base64Decode(Mid(sMessage, I, 4))
Next
End If
End Function
Wow, you must be really baffled now!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|