In the next couple of lesson, we'll show you how to write secure code using the crypto library. In this particular lesson, we will introduce the Crypto API function provided by the PHP programming language or mcrypt library for encryption and decryption. And we choose PHP because PHP as a web programming language allow people to write code that can deploy on a web server. Here we show the process of cipher block chaining mode, CBC for short. We use AES. In this mode, the message is chop into 128 bit, 16-byte block. The last blocks may be padded if the lines of the message is not multiple of 16 bytes. The plaintext box is then exclusive or with initial vector, IV for short. The result and the key are input to the encryption box, implement the AES symmetric encryption standard. The result is 16 bytes cipher block coming out from the bottom of this flow showing in the diagram. The ciphertext block is also of the next initial vector for the next box encryption. Therefore, the related encryption API, the application programming interface, function like call need to mimic that, and therefore it takes in five parameter as is shown at the bottom of the screen there. On the Linux and on Macs, OPENSSL package provides a crypto library for the AES encryption and decryption. Most programming language, Python, Java, Ruby, PHP, all have specific library function that utilize all call wrapped around the OPENSSL crypto library, which is implement in C. For example, the web server-side scripting language PHP has a mcrypt library, a library called mcrypt, that implements the wrapper for the PHP program in order for the program to access the OPENSSL crypto library. And here is how PHP program implements the AES encryption with a CBC operating mode. And there are two constant we specify. One is MCRYPT_RIJNDAEL_128, the other is MCRYPT_MODE_CBC. They define the encryption standard, they define the constant for specifying the operating mode. In PHP, all variables are prefixed with dollar sign similar to a shell programming language. Note that here, $plaintext can be arbitrary lengths, and what the mcrypt_encrypt function call will do is take the plaintext input parameter and then chop them into 16-byte block. If that last block is not 16 byte, by default, you will pad with all zero. If you have a binary data with zero, you need to take special caution and special care by padding it with a special pattern. You can use PKS#7 padding scheme to pad the block and removing the padding character after we do our decryptions. In that case, we don't have to worry about removing the data that actually has zero towards the end. AES is block cipher with block size of 128 bit or 16 byte. If your plaintext is not multiple of 16 byte, you need to pad it up to the next multiple of 16 byte, or by default, the crypto API will pad it with zero. AES standard does not define the padding rule. Just like any standard, there is a implementation methods that leave either the implementation or leave whatever the source code to define that. If the plaintext does not contain binary data zero, you can simply remove the padding zero after the decryption. But, if there are zero data at the end of the block of data, we can use this PKS#7 to encode a padding character with pattern as follows. If there's only one byte to be pad, we'll put 01 there, hexadecimal 01 there. If there are two character to be pad, we will put 02 02 hexadecimal for it and so on. If you have a nine byte, then 09 09 09 and so on. And here, we show how small code, the two-line code, that actually measure how many padding character need to be, and then the next very small code actually repeat the pattern with a single statement. What happen to the 16 byte last plaintext block, happen to be having 01 as the last byte? Now, we will be confused, right? At the end, when we decrypt, is that a 16 byte data with 01 as the data byte, or is that a 16 byte with 01 as a data byte? Solution here is to add one block 16 byte all zero at the end. Just try to figure out the reason behind it. AES has three different key size, 128, 192, 256. How can we generate such bit patterns for the key with precise bit lines? Kind of tricky here. One easy solutions, actually kind of amazing, we can actually use md5 functions, sha256 message digest function. md5 produce 128 bit exactly, sha256 produce 256 bit exactly at the end of the function call, and we can actually provide arbitrary lines kind of mnemonic key as a data, make it easier for us to remember. How about 128 bit key? I will let you figure out as an exercise what kind of function you should use or taking some of the message function and then do some sort of bit mask, remove the remaining bit, that's the hint. PHP's solution is using the hash functions. The hash function provided in PHP allow you to tag three parameter. The first parameter actually indicate the hashing function. In this case, we put in the first parameter as a string, sha256. The hashing function, understand we are using message digest function with sha256 hashing. The second parameter is the mnemonic, the key, or we can call it just the parent tag we try to do hashing. Same thing for md5. md5 has its own name in the PHP. So just md5 taking two parameter, the first parameter is that mnemonic content or the mnemonic key in our case. It will produce 128 bit. Similar to other language also, we'll provide this set of function. In Java, for example, they provide a class called KeyGenerator. Typically, we declare variable such as kg and we assign with KeyGenerator that instance. The parameter we provide there is talking about the kind of key we are going to generate. For example, in this case, we are generate key for AES. And then, with this return handle kg, we can call the method, is method init and provide the parameter which is the key length. It can be 128, it can be 256. In this case, we use 192 and that also provide a solution to the question I just posed to you. And after we set up the kg, we then using kg.generateKey, as a method to generate the lengths of the key. In this case, 128 bit. Mcrypt, a PHP library, provide a function call mcrypt_get_iv_size, which will take two constant, one is the encryption standard, the other is operating mode, and the result is a computed IV size. And what is IV size actually return? The hint here is, see the figure below. Here we have for AES encryption operation. We need to perform exclusive of between the original plaintext box of the data coming in with the initial vector. And just based on that, we know the IV should be having the same bit lengths because one bit by one bit is exclusive so should be the same lengths of the block size. In this case, it is a 16 byte, 128 bit, a typical AES block size. The mcrypt_create the IV functions with the MCRYPT_DEV_URANDOM constant parameter. Basically, we will generate a random number for the IV and this one constant supposed to be using the /etc/urandom for the source of the randomness. Note that IV are often added as prefix before the ciphertext and then send it to the receiver. And the trick here is the receiver doesn't have to generate the initial vector themselves because it generate randomly. It would be tricky for a receiver to figure out what are the random sent and key. A symmetric key encryption takes ciphertext, initial vector, key, for example, 128, 192, or 256 bit of key, and the decryption method to be, we use the AES as the mnemonic name for it. And then we also need to specify the operation mode, either CBC, CFB, CTR content mode. And then it will produce a plaintext back to us. Here is the example of PHP mcrypt_decrypt function call. The plaintext variable will receive this function result. And as you can see, there are five parameter there. The first one is MCRYPT_RIJNDAEL_128, which identify 128 block of RIJNDAEL, which is AES. The next parameter is $key, which is key variable as an input and then ciphertext also an input. The fourth parameter is the CBC, cipher block chaining mode, specified as a constant defined by the function, and the last parameter is initial vector. And result is saved in a plaintext.