The story of the password
Billy Hollis.
March 14, 2002
This article is caused by a problem. I need a way to keep my password in an encrypted file because I need to remember a lot of passwords, but my memory is not as good as before. I know there are many commercial tools that can do this, but I feel it's really good to learn a new technology in. NET.
I completed a simple and complete program with Visual basic®.net to encrypt and decrypt files, and learned a lot from it. Since encryption is an important issue for multiple development, this article describes how to construct such a program.
There are a variety of low-level technologies that can be used for encryption, such as the Microsoft Crypto API. In. NET, these complex content is packaged in each. NET Framework class, and a System.Security namespace contains these cryptographic-related classes. It is not possible to view all the classes in the namespace, but you can probably understand how they work by analyzing a simplest class that encrypts and decrypts using the Data Encryption Standard (DES) algorithm.
As mentioned earlier, we want to perform a complete process of encrypting and decrypting the file, but first we need to explain many of the basic concepts involved in the program. In addition to the principle of cryptography, it is also necessary to briefly discuss the flow in. NET because the cryptographic class is implemented as a stream.
Understanding Flow
A stream is the basic concept of processing bytes in. NET. Here is a brief introduction to its working principle.
Suppose you want to read a file, change all uppercase letters to lowercase letters, and then write the results to another file. Figure 1 shows the diagram of the steps to be completed.
Figure 1: The process of reading a file, processing content, and writing back the results
In. NET, the best way to complete this process is to use a stream. A "stream" is an object used to receive and/or send information bytes. There are two types of streams-back-end and process flow.
Back-end Stream
The back-end stream gets the byte from a location that can hold bytes or stores the byte to that location. A file stream is a back-end stream. The file stream uses the file as the back-end of the byte to store and read or write to the file.
File flows in. NET's
FileStreamClass, which is located in the System.IO namespace.
FileStreamObject uses
ReadAnd
Writemethod to access the file. Will
FileStreamobject is attached to an existing file, you can use the
Readmethod to get the contents of the file in a series of bytes. and use
WriteMethod,
FileStreamObject can write a series of bytes to a file (an existing file or a new file).
FileStreamClass also uses the
Seekmethod to locate a specific location in the file.
Other examples of back-end streams are network flows (putting data on the TCP/IP stack or getting data from it) and memory flow (using memory as a temporary backend). Their basic structure and
FileStreamObjects are the same, using the
ReadAnd
WriteMethod accesses the bytes of the back-end store. Some back-end streams, such as network streaming, do not support
SeekMethod because there is no permanent storage content to perform the lookup operation.
Process Flow
The procedure flow is used to receive and process bytes, and then writes bytes to other streams (usually the back-end stream). For example, we can start with the name
Stream. NET base class, and then create a process flow that changes uppercase letters to lowercase letters. Then attach the stream to any back-end stream. Now, the relationship of the diagram above can be expressed as Figure 2.
Figure 2: The process of reading a file, processing content, and writing back the results using a stream representation
Our "lowercase" stream class is only useful when it is often necessary to perform this operation. However, this class of streaming can perform the various operations required by its byte.
encryption in. NET
In. NET, encryption and decryption are implemented using process flow. For example, the typical steps for encryption are:
- Incoming bytes from an input stream (for example, an unencrypted file on a disk).
- The byte is sent to the encrypted stream, and the encrypted stream itself is connected to an output stream (for example, a file to hold the encrypted data).
- The cryptographic stream encrypts bytes and automatically places the bytes in the associated output stream.
The cryptographic stream is encapsulated into a
CryptoStreamClass (The class is described in detail later in this article). Assuming that we are reading and writing disk files, if this term is used, then the relationship of this procedure is shown in Figure 3.
Figure 3: The process of encrypting a file
Encryption type
The method of encrypting information has been hundreds of years old. The novelist Allen Poe once dabbled in cryptography, and designing and deciphering passwords was an important activity in World War Ii. However, the advent of computers has led to a rapid development of cryptography. The powerful computer's ability to analyze encrypted messages forces people to constantly study cryptographic techniques that are increasingly difficult to decipher.
The result is a variety of encryption methods. The common methods available in. NET include: Cryptographic methods. NET class Data Encryption Standard (DES) symmetry for general type implementations
(private key) DESCryptoServiceProviderRC2 (RSA Data Security, Inc.) Symmetric
(private key) Rc2cryptoserviceproviderrijndael symmetry
(private key) Rijndaelmanagedtripledes (using triple DES encryption on one line) symmetry
(private key) TripleDESCryptoServiceProvider digital Signature Algorithm Asymmetric
(Public key) Dsacryptoserviceproviderrsa (invented by Rivest, Shamir and Adelman, named after the initials of their names) asymmetric
(Public key) RSACryptoServiceProvider
The general types of cryptographic algorithms are symmetric and asymmetric. Symmetric algorithms use the same key to encrypt and decrypt data. An asymmetric algorithm uses one public key for encryption and another key to decrypt it. At the end of this article, we will continue to introduce this point.
If you're using encryption only, you don't have to know how it works (thankfully, something is quite complex), but if you choose an algorithm, you must consider the following three main factors:
- The difficulty of cracking messages encrypted using the algorithm
- Performance of the algorithm
- Security of Keys
There are a number of WEB sites that discuss these factors. For starters, the following two sites are more suitable: http://www.microsoft.com/china/security/and Snake oil FAQ http://www.interhack.net/people/cmcurtin/ Snake-oil-faq.html (English).
Use the. NET Encryption Class
The. NET classes listed in this table are in the System.Security.Cryptography namespace, so you must reference System.Security.dll when you use them. In addition, use a pair of
IMPORTSStatement to reference a namespace makes the code more concise:
Imports System.securityimports System.Security.Cryptography
The classes in the previous table are all the same as the one named
CryptoStreamThe general password Stream class works together. This allows the flow operation to be handled using only a class that implements multiple types of encryption. You can even create your own cryptographic class and insert it into the
CryptoStream(although its security is less likely than the class listed in the table above).
In our example, the encryption method we use might be the simplest in. NET, that is, symmetric key encryption using the DSE algorithm. The process stream that implements DES is called DESCryptoServiceProvider.
Most symmetric algorithms require two separate byte arrays for the encryption process. The first one is the key. For DES, the key is 8 bytes, while the other algorithms use a different number of bytes.
The private key must be passed to the person who decrypted the file in a secure manner, and the encrypted information will be compromised if the private key is compromised. But even if the key does not leak, DES encryption is also working, this encryption method is far from being the most secure algorithm.
To encrypt an information block (usually 8 bytes), you need to use both the key and the encrypted result of the previous block, that is, a block with the same original character will not produce the same result after encryption. The advantage of this is that repeated blocks do not provide clues to make encrypted cracking easier.
However, the first block does not have a leading block as an input for encryption. If the first block contains known information (such as a network header), the first block is reverse engineered, and the key is easily obtained.
To prevent this, DES uses so-called "initialization vectors". This is another byte array with the same length as the key. Use it with the key to further encrypt the first block of 8 bytes. There are several other symmetric algorithms that also use initialization vectors.
Create key
The symmetric encryption algorithm is the safest if you use an accompanying secret key. So the best way to generate a key is to use a random process to get the 8 bytes you need. However, 8 random bytes are not easy to remember. In the following example, we use "password" to generate the key. Simply put, the password is a 8-character string that initializes the byte array that makes up the key using the ASCII value of the character.
We need two such passwords: one for the key and another for the initialization vector. This is far from the safest way to generate a key, but it is more appropriate for our example, and it provides the appropriate level of security for regular use.
encryption/Decryption program
Now that we've covered the concept, we're ready to start creating the program to encrypt and decrypt the file. We designed it as a Windows forms application.
Create a new Windows forms application in Visual Studio. To access your password class, go to the
Project | ADD Reference(Project | Add a reference), add a reference to the System.Security.
The forms in your project need four labels and four text boxes that are side-by, close to the bottom with two buttons, and a status bar at the base. When you are finished, the form should look like Figure 4.
Figure 4: The form layout for the encryption/decryption program
Use the following name to set the text box from top to bottom:
- Txtunencryptedfile
- Txtencryptedfile
- Txtkeypassword
- Txtivpassword
of the individual text boxes
Textproperty is set to null. To name the status bar
Sbencryptionstatus。
Name the button
BtnencryptAnd
Btndecrypt, and put their
Textproperty is changed to
EncryptAnd
Decrypt。 For
Btnencryptbutton to add the following code:
Dim Bytekey () as Bytebytekey = Getkeybytearray (txtkeypassword.text) Dim byteinitializationvector () as Bytebyteinitializationvector = Getkeybytearray (txtivpassword.text) Encryptordecryptfile (TxtUnencryptedFile.Text, _ Txtencryptedfile.text, _ Bytekey, Byteinitializationvector, _ Cryptoa Ction.actionencrypt)
For
Btndecryptbutton to add the following code:
Dim Bytekey () as Bytebytekey = Getkeybytearray (txtkeypassword.text) Dim byteinitializationvector () as Bytebyteinitializationvector = Getkeybytearray (txtivpassword.text) Encryptordecryptfile (TxtEncryptedFile.Text, _ Txtunencryptedfile.text, _ Bytekey, Byteinitializationvector, _ CRYPTOAC Tion.actiondecrypt)
You will notice that the two buttons are similar to each other in code. They use the same function to get an array of keys and initialization vectors and use the same function (named
Encryptordecryptfile) Encrypt or decrypt the file. Use
EncryptordecryptfileThe only difference is that the file name of the input and output files in the text box is the exact opposite, and the action (encrypted or decrypted) is different.
The action is specified as
cryptoactionEnumeration type, so you need to define enumerations. Add this code below the Inherits System.Windows.Forms.Form line:
Private enum Cryptoaction actionencrypt = 1 Actiondecrypt = 2End enum
You also need to add statements at the top of the module so that you can easily reference password classes and stream classes. Here is the line of code you want:
Imports System.Security.CryptographyImports System.securityimports System.IO
So far, the code is relatively simple. Now let's see how to generate the key. The following is a function that converts a password into a byte array, which should be added to the form code:
Private Function Getkeybytearray (ByVal Spassword as String) as Byte () Dim bytetemp (7) As Byte Spassword = Spassword. PadRight (8) ' Make sure it is 8 characters Dim Icharindex as Integer for icharindex = 0 to 7 bytetemp (icharindex) = ASC (mid$ (s) Password, Icharindex + 1, 1)) Next return bytetempend Function
This is also a very intuitive piece of code. Visual Basic 6.0 developers should be aware of the
PadRightMethod (instead of the equivalent string handling code in Visual Basic 6.0) to ensure that the length is correct.
The following are key elements. Insert the following function to handle encryption and decryption:
Private Sub encryptordecryptfile (ByVal sinputfile as String, _ byval sOutputFile as String, _ byval Bytedeskey () as Byte, _ byval Bytedesiv () as Byte, _ byval Direction as Cryptoaction) ' ChuangA file stream that is built to handle input and output files. dim fsinput as New FileStream (Sinputfile, _ filemode.open, FileAccess.Read) Dim Fsoutput as New FileStream (sOutputFile, _ filemode.openorcreate, FileAccess.Write) Fsoutput.setlength (0) ' encryption/decryption process required variable dim bytebuffer (4096) as Byte ' Save a byte block for processing dim nbytesprocessed as Long = 0 ' to run the count of encrypted bytes dim Nfilelength As Long = Fsinput.length dim Ibytesincurrentblock as integer Dim Desprovider as New descryptoserviceprovider () dim Csmycryptostream as CryptoStream dim sdirection as string ' set to encrypt or decrypt select case Direction case cryptoaction.actionencrypt csmycryptostream = New CryptoStream (fsOutput, _ desprovider.createencryptor ( Bytedeskey, Bytedesiv), _ cryptostreammode.write) Sdirection = "Encryption" case cryptoaction.actiondecrypt csmycryptostream = New CryptoStream (fsOutput, _ desprovider.createdecryptor (ByteDESKey, BYTEDESIV), _ CryptoStreamMode.Write) sdirection = "decryption" end Select sbencryptionstatus.text = sDirection + "Starting ..." read from input file, then encrypt or decrypt and write to output file. while nbytesprocessed < nfilelength Ibytesincurrentblock = fsInput.Read (bytebuffer, 0, 4096) Csmycryptostream.write (bytebuffer, 0, Ibytesincurrentblock) nbytesprocessed = nbytesprocessed + CLng (ibytesincurrentblock) Sbencryptionstatus.text = sdirection + _&NBSP;&NBSP;&NBSP;&NBSP;&Nbsp; "Processing-Processed bytes-" + _ nBytesProcessed.ToString end While sbencryptionstatus.text = "complete" + sdirection + _ & nbsp; ". Total bytes Processed-"+ nbytesprocessed.tostring csmycryptostream.close () Fsinput.close () fsoutput.close () End Sub
Now let's specify the above code.
The first paragraph creates a file stream object named
fsinputAnd
FsoutputThat is used to get input from the file being read and then output to a new file. Then is the declaration of several variables and objects needed in the rest of the function. The elements declared are as follows:
- Bytebuffer: An array of bytes used to process the current block of data. Fills the array by reading the input file, and then passes it to the CryptoStream object for encryption. The following code has a loop that reads the input file, extracts the contents of the file with a block size of 4096 bytes, and puts it in the bytebuffer.
- nbytesprocessed: The total number of bytes in the input file processed so far.
- nfilelength: The length of the input file.
- Ibytesincurrentblock: The number of bytes processed in a particular iteration of the loop. In addition to the last time, each iteration is 4096 bytes. In the last iteration, the number of bytes is the number of bytes remaining in the last block of the file (typically less than 4096).
- Desprovider: insert it into the CryptoStream to provide the encryption/decryption functionality to use.
- Csmycryptostream: is a CryptoStream object that is used for encryption or decryption.
- sdirection: is a cryptoaction value (Actionencrypt or Actiondecrypt) indicating the action to be performed by executing this function.
The next section is
Select Case, set to encrypt or decrypt, depending on what we do with the function.
DESCryptoServiceProvidercan be used separately
CreateEncryptorOr
CreateDecryptormethod to create a cryptographic device or a decryption device. This is used to instantiate what we want to use
CryptoStreamObject, and is named
Csmycryptostream。
CsmycryptostreamObject also needs to know which stream to use for output. To do this, in the instantiation of
CsmycryptostreamIn the process, both encryption and decryption specify the Fsoutput stream.
We also set up a string for the status bar message with the value "encrypted" or "decrypted."
The last paragraph actually performs encryption and decryption.
whileLoops read data from an input file and read one block at a time. Then use its
WriteMethod to write a block to the
CsmycryptostreamIn After
CsmycryptostreamThe encryption or decryption is performed automatically, and the results are written to the attached file stream fsoutput. The total number of bytes processed and status bar messages are then updated and the loop is executed to handle another block.
After the loop completes, the status bar text is updated and the stream object is closed, and the entire process ends.
Now we can test the project. To do the correct testing, encrypt the file size appropriately. I use a text file obtained from Project Gutenberg (http://promo.net/pg/[English]), which provides a variety of text files that can be downloaded and not subject to copyright restrictions. The file I chose was Doyle's collection of Sherlock Holmes. The text file length is 573 KB.
In
unencrypted File(unencrypted file) text box, enter the path name of the file you selected to encrypt;
Encrypted File(Encrypted file) text box, enter the path name of the encrypted file. You also need to construct a password for the key and initialization vectors.
In the test, I used the 700-mhz Pentium III computer, the encryption size of 573 KB of the "Sherlock Holmes collection" in less than two seconds. This shows one of the advantages of the DES algorithm, which is its superior performance.
If you open the output file after the test, you will see that the file is fully encrypted. Now, use the same password to decrypt it to another file. You may want to make sure that the new decrypted file is exactly the same as the original file. In Microsoft Windows®, there is a command-line utility called FC (file comparison) that you can use to test.
Obviously, if you change the password when you decrypt it, the decryption will not work. However, if you change the initialization vector when decrypting, something interesting happens. The file is normally decrypted except for the first 8 characters. In other words, the initialization vector can only protect the first block.
Summary
As mentioned above, the DES algorithm is just an option. One of the most flexible options is the use of public-key cryptography, also known as asymmetric encryption. In this technique, encryption and decryption use different keys. The encryption key is public and the decryption key is confidential and is known only to the person who needs to perform the decryption. Everyone can encrypt with an encryption key, but can only decrypt it using the decryption key.
The biggest disadvantage of public key cryptography is its poor performance. Symmetric algorithms have a much lower demand for processing power than public-key algorithms. However, public-key cryptography makes it possible for everyone, even people you don't know, to encrypt and send it to you, which gives you more flexibility.
Regardless of which encryption technology you choose, using the. NET Password class makes the operation easier. As the example in this article shows, you only need to provide the necessary keys and other parameters, and then insert the password class into the appropriate stream. This provides greater convenience for creating Visual Basic. NET applications that use encryption technology.