# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  Add Powerful Encryption To Your Visual Basic Programs

## Maven

I thought I would show you an easy way to add powerful encryption to your visual basic programs. Up till now, you either had to write the chipers in a fast language like C or deal with the CryptoAPI. Either way you went, it was very complex with uneven documentation. But lucky for the visual basic programmer, Microsoft released the CAPICOM component, which is a wrapper around the CryptoAPI. This is just a few examples of how to use it.

Installing CAPICOM:

The first thing you have to do is download CAPICOM. The CAPICOM component is available at: http://www.microsoft.com/downloads/r...eleaseID=44155

Once you have that downloaded, extract the CAPICOM.DLL file into your system directory (system32 on xp). Then open up your command prompt (dos on some machines) and change directories to c:\windows\system32 (c:\windows\system\ on some platforms). Then type this into the command prompt and hit enter:
regsvr32.exe CAPICOM.DLL

You should see a message box telling you the install was successful.


Using CAPICOM:

Before we can use CAPICOM from our visual basic program, we must first add a reference to it. You can do so by going to Project in your menu and then References. Tick the CAPICOM type library and hit ok. Now you can call the CAPICOM functions from within visual basic.

Add the following to your form:


Make this text box big:
Text Box  Name=txtMessage, text=nothing, Multiline=true

Text Box  Name=txtPassword, text=nothing, passwordchar=*
Command Button  Name=cmdDecrypt, text = Decrypt
Command Button  Name = cmdEncrypt, text = Encrypt

Then paste the following code into your forum.



```
Private Sub cmdDecrypt_Click()
    'Make sure we have entered all the information:
    If txtMessage.Text <> "" And txtPassword <> "" Then
        
        'This is our encryption object
        Dim DecryptData As New EncryptedData
        
        'We send the object the password to use to unlock the encryption:
        DecryptData.SetSecret (txtPassword.Text)
        
        'Send the ciphertext to the object and tell it to decrypt it.
        DecryptData.Decrypt (txtMessage.Text)
        
        'Get our plaintext from the object
        txtMessage.Text = DecryptData.Content
    End If
End Sub

Private Sub cmdEncrypt_Click()
    'Make sure we have entered all the information:
    If txtMessage.Text <> "" And txtPassword <> "" Then
    
        'This is our encryption object
        Dim encryptdata As New EncryptedData
    
        'Before we can start encrypting, we got to define the
        'algorithm, keysize, and the password (Used to generate key)
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'Algorithm to use: AES (Advanced Encryption Standard)
        encryptdata.Algorithm = CAPICOM_ENCRYPTION_ALGORITHM_AES
        
        'You could also use:
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        'encryptdata.Algorithm =CAPICOM_ENCRYPTION_ALGORITHM_3DES
        'encryptdata.Algorithm = CAPICOM_ENCRYPTION_ALGORITHM_DES
        'encryptdata.algorithm = CAPICOM_ENCRYPTION_ALGORITHM_RC2
        'encryptdata.Algorithm = CAPICOM_ENCRYPTION_ALGORITHM_RC4
        
        'Next we set our key size, which is a no brainer to put to max.
        encryptdata.Algorithm.KeyLength = CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM
        
        'Next we set our secret password to unlock the message.
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        encryptdata.SetSecret (txtPassword.Text)
        
        'We send the object the plaintext scramble:
        encryptdata.Content = txtMessage.Text
        
        'Return message as base64
        txtMessage.Text = encryptdata.Encrypt(CAPICOM_ENCODE_BASE64)
    End If
End Sub
```

I've also added the project (For those of u with vb 6)

----------


## dglienna

Note:  This doesn't run under Windows 2000 (with up to date service packs)

I compiled the project, and it didn't run. It works fine under XP Home.

Just found this, and it DOES work on both platforms. I don't know why.



```
Option Explicit 

Dim sSecretData
sSecretData = "Here is some very secret data." 

' Build up the key
Dim wshNetwork, sComputerName
Set wshNetwork = WScript.CreateObject("WScript.Network") 
sComputerName = wshNetwork.ComputerName

Dim capEData
Set capEData = CreateObject("CAPICOM.EncryptedData")

capEData.Algorithm = 3 'Use 3DES
capEData.SetSecret sComputerName 
capEData.Content = sSecretData

Dim sCipherText
sCipherText = capEData.Encrypt

capEData.Algorithm = 3
capEData.SetSecret sComputerName 
capEData.Decrypt sCipherText

Dim sPlainText
sPlainText = capEData.Content 

MsgBox "Original data: " & sSecretData & chr(13) _ 
  & "Encrypted data: " & sCipherText & chr(13) _ 
  & "Recoverd data: " & sPlainText
```

----------


## dglienna

I'm hoping that 3DES is the missing key here.  Testing it out.


Hot-DAMN.  Wasted a whole day when it was something so simple.

EVERYBODY.  DO USE 3DES encryption if you want it to work accross platforms.

----------


## Maven

> I'm hoping that 3DES is the missing key here.  Testing it out.
> 
> 
> Hot-DAMN.  Wasted a whole day when it was something so simple.
> 
> EVERYBODY.  DO USE 3DES encryption if you want it to work accross platforms.


That com is just a wrapper around the windows crypto API. Different versions of windows support different key sizes, different ciphers, etc.

----------


## kyrathaba

Could you show a simple example of using CAPICOM to encode a binary file, such as myprog.exe or myarchive.zip, rather than a string?

----------


## Maven

It should work the same way with binary. Just make sure you use byte data types instead of string. If you want the results stored as binary instead of base64 then you need to use CAPICOM_ENCODE_BINARY.


While I'm here, this is how you hash data:
Dim x As New HashedData
x.Algorithm = CAPICOM_HASH_ALGORITHM_MD5
x.Hash ("Hash This")
Text1.Text = x.Value

----------


## dglienna

isn't there a way to encrypt a whole file at once, like an attachment to an email?  I got that from the website, but they didn't give any examples. If you wanted to encrypt an .exe, you'd have to read the binary file, and encrypt it by encrypting each byte, or what?

----------


## Maven

> isn't there a way to encrypt a whole file at once, like an attachment to an email?  I got that from the website, but they didn't give any examples. If you wanted to encrypt an .exe, you'd have to read the binary file, and encrypt it by encrypting each byte, or what?


I'm not aware of any functions for encryption a file. Would definitly make life a lot simpler though wouldn't it? You would do it just like a string with the exception that it would be a byte array instead of a string array. Just make sure when you read the file, you do it as binary and not as string (text).


Later on I may write a decent cipher library but as for right now I'm working long ass hours and have very little time =/

----------


## Maven

> I'm not aware of any functions for encryption a file. Would definitly make life a lot simpler though wouldn't it? You would do it just like a string with the exception that it would be a byte array instead of a string array. Just make sure when you read the file, you do it as binary and not as string (text).
> 
> 
> Later on I may write a decent cipher library but as for right now I'm working long ass hours and have very little time =/


The cryptoAPI may have a function for that though. I'm not prepaired to explain that API set though, it's huge and cumbersome. When work slows down a bit maybe I'll write a few tuts on using it. Till then =P

----------


## kyrathaba

The MSDN site suggests that EncryptedData.Content must be set equal to a string.  At least, that's how it reads to me.  I tried taking some example code and modifying it to use byte arrays, but was unsuccessful.  I've been scouring the internet looking for a freeware ActiveX control that would encapsulate functionality to encrypt and decrypt non-text files, but haven't been successful yet.  If anyone knows of any, please post a link.

----------


## dglienna

sounds good. i just heard about the CryptoAPI, and don't know what method it used to encrypt data.  Someone else found the Encrypt() parameter.

----------


## Maven

> The MSDN site suggests that EncryptedData.Content must be set equal to a string.  At least, that's how it reads to me.  I tried taking some example code and modifying it to use byte arrays, but was unsuccessful.  I've been scouring the internet looking for a freeware ActiveX control that would encapsulate functionality to encrypt and decrypt non-text files, but haven't been successful yet.  If anyone knows of any, please post a link.


The reason I said it should work is because I convert a string into bytes and then used that to be encrypted and didn't have any problems. 



```
Dim pk As String
Dim msg() As Byte
Dim base64 As String

Private Sub Command1_Click()
    Dim x As New EncryptedData
        
    x.Algorithm.KeyLength = CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM
    x.Algorithm.Name = CAPICOM_ENCRYPTION_ALGORITHM_AES
    
    x.SetSecret (pk)
    
    x.Content = msg
    base64 = x.Encrypt(CAPICOM_ENCODE_BASE64)
    
    Text1.Text = base64
    
End Sub

Private Sub Command2_Click()
    Dim x As New EncryptedData
    
    x.SetSecret (pk)
    x.Decrypt (base64)
    Text1.Text = StrConv(x.Content, vbUnicode)
    
    
End Sub

Private Sub Form_Load()
    Dim x As String
    x = "Hello Wonderful World"
    msg = StrConv(x, vbFromUnicode)
    pk = "test"
End Sub
```

----------


## Maven

> The MSDN site suggests that EncryptedData.Content must be set equal to a string.  At least, that's how it reads to me.  I tried taking some example code and modifying it to use byte arrays, but was unsuccessful.  I've been scouring the internet looking for a freeware ActiveX control that would encapsulate functionality to encrypt and decrypt non-text files, but haven't been successful yet.  If anyone knows of any, please post a link.


Well if you had to, just convert the binary file into base64 and then encript that.

----------


## sacramento

hi Maven:

I had try your code and work perfectly...
now I would like to encrypt the password of my DB in access!THis is possible? How?

This is the way I open the DB:


VB Code:
Set db = Workspaces(0).OpenDatabase(App.Path & "\progaves.mdb", False, False, ";pwd=agaporni")


Thanks

----------


## batserra

Hi ,i have a problem with encrypt binary files ,i have got a simple aplication to encrypt files (some txt and some binary) ,i have done this:
InFile/OutFile  its a string with the file to encrypt

To encrypt:

     Dim buffer As String
     Open InFile For Binary As #FileO
        buffer = Input$(LOF(FileO), FileO)
     Close #FileO
     Dim x As New EncryptedData
     Dim base64 As String

     x.Algorithm.KeyLength = CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM
     x.Algorithm.Name = CAPICOM_ENCRYPTION_ALGORITHM_AES
     x.SetSecret (Key)
     x.Content = buffer
     base64 = x.Encrypt(CAPICOM_ENCODE_BINARY)
     sfo.DeleteFile (OutFile)
     Open OutFile For Binary As #FileO
          Put #FileO, , base64
     Close #FileO

To Decrypt:

     Open InFile For Binary As #FileO
          ReDim msgbyte(0 To LOF(FileO))
          msgbyte = Input$(LOF(FileO), FileO)
     Close #FileO
     If FileExist(OutFile) = True Then sfo.DeleteFile (OutFile)
     Dim x As New EncryptedData
     x.SetSecret (Key)
     x.Decrypt (msgbyte)
     FileO = FreeFile
     Open OutFile For Binary As #FileO
     Put #FileO, , x.Content
     Close #FileO

-----------

Firts at tryed ,with encrypt txt files ,with string not a byte varible and works ok for binary and txt files, but the file it's really large ,with this ,the encryption create a file as large as the original ,but i can't decrypt i recive a message at the line   x.Decrypt (msgbyte) ,with -2146881269 error and something about ASN1 incorrect.

Thanks to all, and sorry for my english

----------


## asif_14443

Mr. Maven, This link does not work 

http://www.microsoft.com/downloads/...ReleaseID=44155

and shows this message :-

*The download you requested is unavailable. If you continue to see this message when trying to access this download, go to the "Search for a Download" area on the Download Center home page.*  

is the URL is correct... ??? or expired.. ???

I am working on a project in VB ,, is it possible that I encrypt my exe file,, so no one can read it again by using some VB Decoding softwares for Project Source Code. please suggest for encoding....

----------


## Maven

> Mr. Maven, This link does not work 
> 
> http://www.microsoft.com/downloads/...ReleaseID=44155
> 
> and shows this message :-
> 
> *The download you requested is unavailable. If you continue to see this message when trying to access this download, go to the "Search for a Download" area on the Download Center home page.*  
> 
> is the URL is correct... ??? or expired.. ???
> ...


It's just expired, microsoft likes to change their urls. 

Just do a search for CAPICOM at their site. 

peace

----------


## Al42

Even searching the site isn't as easy as it could be.  The current location starts here: http://www.microsoft.com/downloads/d...DisplayLang=en

----------


## anufabian

I have followed the code snippet given by you and implemented the encrytion using C#. I am encrypting a string and sending this string as a querystring to a site which has to decrypt the same string and give me an authenticated login followed by the display of a page at their end.

My problem is, at times the whole process takes place fine, but at certain times when i go for accessing the url using the encrypted value , I get a page cannot be displayed(custom error page of IIS for error number 404).

Can u please tell me is it relating to any specific settings that has to be done at my end , or is it because of the problem of decrytion at their end. Both the parties have agreed in using a single key for encrytion and decryption.

I am using Windows Xp.

Please help , its very urgent,.

----------


## Maven

> I have followed the code snippet given by you and implemented the encrytion using C#. I am encrypting a string and sending this string as a querystring to a site which has to decrypt the same string and give me an authenticated login followed by the display of a page at their end.
> 
> My problem is, at times the whole process takes place fine, but at certain times when i go for accessing the url using the encrypted value , I get a page cannot be displayed(custom error page of IIS for error number 404).
> 
> Can u please tell me is it relating to any specific settings that has to be done at my end , or is it because of the problem of decrytion at their end. Both the parties have agreed in using a single key for encrytion and decryption.
> 
> I am using Windows Xp.
> 
> Please help , its very urgent,.


This problem could be located in various places in your code outside of the actual encryption/decryption process. 404 error means that the server couldn't find the page thats being requested. So the problem you are having could be any where during that process. 

As far as the cipher goes, as long as your using the same key and your message isn't being modified during the transaction you should always get the same result. So you could have a problem with the way your url is being decoded, but even then it should throw a message such as bad data or corrupt data when the cipher goes to decrypt it. 

........................................

Someone sent me a pm asking for me to repost:
I just threw together a very simple example....

----------


## anufabian

But even if I trap the 404 error the max is I can show the user some custom page, but my problem is why doesn't the page get displayed at times. 

How can i trace this issue, please could u give me a solution.

----------


## Maven

> But even if I trap the 404 error the max is I can show the user some custom page, but my problem is why doesn't the page get displayed at times. 
> 
> How can i trace this issue, please could u give me a solution.


It's somewhere in the process of that page being requested. It could be anywhere though-out that process. From the point a user makes a request for content, to the point of it being served. I don't know what all is being done throughout your code, from point a to point b. I don't know if you're sending this information via get or post. If your not sending it post, then do so. Also make sure you are encoding your information in base64 and not in binary, if you try to send binary over the internet, it will be corrupted during the translation. Outside of that, you may be getting invalid input or having some other type of error in the logic of your code. It's unlikely to be the cipher itself.

The crytpoAPI gets a huge amount of use by quite honestly, most of the entire internet. When you go to amazon and enter in your credit card, most likely the crytpoAPI is being called at some point or other. CAPICOM is just a wrapper around those API's. 

On a side note, 
If you are using this in an attempt to protect users that are transmitting information to your web server, understand there is little to no protection what so ever being done. The reason is, all a person would have to do to crack the protection is decompile the resource and pull out the password. At that point, they would be able to read everything from all users. In this situation, public key encryption is the method to use for best protection. It generates a random session key just for one time of sending a message, after that the session key is discarded. Public key encryption is what you want to use when you're dealing with encryption of multiple users thats is being transmitted. 

Symmetrical encryption is what is shown in this example. Which is more useful for protecting files on your computer, where you alone would only want access to. This is because the password or key thats being used for decryption isn't stored or transfered. It should only exist in your head. Also note that when you use this form of encryption, you *MUST* zero out the hard drive where the plain text was once located. Just because you delete a file doesn't mean it's deleted, it's still there, it just gets erased out of the tree. In other words, it makes a little mark saying this space is free again and thats all. It doesn't actually go to that space and change anything. It just sits there until one day its over-written by some other file. Therefore if you used even the most perfect cipher like the one-time pad, that information isn't going to be protected if someone can just read the hard-drive on low level and pull out the original plain text.

----------


## anufabian

will give u the code snippet that I am actually using 

I am encoding some thing and then sending it to site and they have to decrypt it and then allow me to do a login to their page

string strencrypteddata="";
EncryptedData encryptdata = new EncryptedDataClass(); 

encryptdata.Algorithm.Name = CAPICOM.CAPICOM_ENCRYPTION_ALGORITHM.CAPICOM_ENCRYPTION_ALGORITHM_3DES;

encryptdata.Algorithm.KeyLength = CAPICOM.CAPICOM_ENCRYPTION_KEY_LENGTH.CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM;

encryptdata.SetSecret("SecretKey",CAPICOM.CAPICOM_SECRET_TYPE.CAPICOM_SECRET_PASSWORD);

encryptdata.Content = "Secret Content";			

HtmlControl orgframe = (HtmlControl)this.FindControl("nameofIframe"); 

orgframe.Attributes["src"]=("http://sitename/defaultpage.asp?Content =" + encryptdata.Encrypt(CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64) );


I am using the base 64 and the method is post. I am loading the document into an Iframe.

Could u please say wat must be going wrong in this case.


Please help. Please tell me how I can trace the problem

----------


## Maven

> will give u the code snippet that I am actually using 
> 
> I am encoding some thing and then sending it to site and they have to decrypt it and then allow me to do a login to their page
> 
> string strencrypteddata="";
> EncryptedData encryptdata = new EncryptedDataClass(); 
> 
> encryptdata.Algorithm.Name = CAPICOM.CAPICOM_ENCRYPTION_ALGORITHM.CAPICOM_ENCRYPTION_ALGORITHM_3DES;
> 
> ...





> orgframe.Attributes["src"]=("http://sitename/defaultpage.asp?Content =" + encryptdata.Encrypt(CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64) );


The "Content =" should probably look like "Content=". I would also consider changing the plus to an ampersand &. 




> orgframe.Attributes["src"]=("http://sitename/defaultpage.asp?Content=" & encryptdata.Encrypt(CAPICOM.CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64) );


Make sure that you are accessing your "Content" variable the same way throughout your code. The way you have it defined here, it would be "Content ", and not "Content". So if you have that mixed up anywhere, it will cause it to return invalid data.

Thats pretty much the only signs of a possible hick-up I see from this end of the code.

BTW - If you're doing this in .net, I would suggest using the built in functions that are under the security namespace. They are called for the most part, in the same fashion.

----------


## anufabian

I am using the + , as the code is wriiten in C#. Secondly I am not accessing the Content any where ,hence there is no way of Content being misspelled.

Can i .Net related System.Security functions for Capicom. Because the server on to which I am doin an encrypted login has the code written in Capicom.

----------


## learning c

any code that is actually secure against governments and large corporations?

----------


## Maven

> any code that is actually secure against governments and large corporations?


Secure as you can get without breaking export laws =P

----------


## learning c

lol  :Wink:

----------


## anufabian

Thanks for the supprot that you have given through your code snippets and explanations.

My problem has been resolved.

Thanks a lot

----------

