⬆️ ⬇️

Cryptography in Java. Class cipher

Hi, Habr! I present to you the translation of the second article "Java Cipher" by Jakob Jenkov from the series of articles for beginners who want to learn the basics of cryptography in Java.



Table of contents:



  1. Java Cryptography
  2. Java cipher
  3. Java MessageDigest
  4. Java Mac
  5. Java Signature
  6. Java KeyPair
  7. Java KeyGenerator
  8. Java KeyPairGenerator
  9. Java KeyStore
  10. Java keytool
  11. Java Certificate
  12. Java CertificateFactory
  13. Java CertPath


Java Cipher (Cipher)



The Java Cipher class ( javax.crypto.Cipher ) is an encryption algorithm. The term "Cipher" is the standard term for the encryption algorithm in the world of cryptography. This is why the Java class is called Cipher , not the Encoder / Decoder or something else. You can use an instance of Cipher to encrypt and decrypt data in Java. This chapter explains how the Cipher class works.



Creating a cipher



Before using a cipher, you must create an instance of the Cipher class by calling its getInstance () method with a parameter indicating which type of encryption algorithm you want to use. Here is an example of creating an instance of Java Cipher:



Cipher cipher = Cipher.getInstance("AES"); 


This example creates an instance of Cipher using the AES encryption algorithm.



Encryption Modes



Some encryption algorithms can work in different modes. Encryption mode determines the details of how the data will be encrypted. Thus, the encryption mode partially affects the encryption algorithm. Encryption modes can sometimes be used in several different encryption algorithms — as a method that is added to the basic encryption algorithm. That is why the modes are considered separately from the encryption algorithms themselves, but rather as “additions” to the encryption algorithms. Here are some of the most well-known encryption modes:





When creating a cipher instance, you can add its mode to the name of the encryption algorithm. You can create an AES Cipher instance using Cipher Block Chaining (CBC) mode, like this:



 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 


Since the cipher block chaining mode also requires an “add-on scheme”, an add-on scheme ( PKCS5Padding ) is added to the end of the string of the name of the encryption algorithm.

It is important to know that not all algorithms and encryption modes are supported by the default Java SDK encryption provider. You may need to install a third-party provider, such as Bouncy Castle, to create the required cipher instance with the required mode and filling scheme.



Cipher Initialization



Before using a Cipher instance, it must be initialized. Initialization of the cipher is performed by calling its init () method. The init () method takes two parameters:





An example of initializing an instance of Cipher in encryption mode:



 Key key = ... // /    cipher.init(Cipher.ENCRYPT_MODE, key); 


And here is an example of initializing a Cipher instance already in decryption mode:



 Key key = ... ///    cipher.init(Cipher.DECRYPT_MODE, key); 


Data Encryption and Decryption



To encrypt or decrypt data using an instance of Cipher, one of these two methods is called:





There are several overridden versions of the update () and doFinal () methods that accept different parameters. Consider the most commonly used here. If you need to encrypt or decrypt a single data block, simply call doFinal () with the data to encrypt or decrypt. Example:



 byte[] plainText = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] cipherText = cipher.doFinal(plainText); 


In fact, the code looks much the same in the case of decrypting data. Just remember that the Cipher instance must be initialized in decryption mode. Here is the decryption of a single block of cipher text:



 byte[] plainText = cipher.doFinal(cipherText); 


If you need to encrypt or decrypt a large file divided into several blocks, update () is called once for each data block and ends with a call to the doFinal () method with the last data block. Here is an example of encrypting multiple data blocks:



 byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8"); byte[] data3 = "01234567890123456789012345".getBytes("UTF-8"); byte[] cipherText1 = cipher.update(data1); byte[] cipherText2 = cipher.update(data2); byte[] cipherText3 = cipher.doFinal(data3); 


The reason why the doFinal () call is required for the last data block is that some encryption algorithms must complement the data in order to fit a specific cipher block size (for example, an 8-byte boundary). It is not necessary to supplement intermediate encrypted data. Consequently, the update () method is called for the intermediate data blocks and the doFinal () call for the last data block.

When decoding multiple data blocks, you also call the update () method for the intermediate data blocks and the doFinal () method for the last block. An example of decrypting several data blocks:



 byte[] plainText1 = cipher.update(cipherText1); byte[] plainText2 = cipher.update(cipherText2); byte[] plainText3 = cipher.doFinal(cipherText3); 


Again, the cipher instance must be initialized in decryption mode for this example to work.



Encryption / Decryption of part of a byte array



Encryption and decryption methods of the Cipher class can encrypt or decrypt some of the data stored in a byte array. The update () and / or doFinal () method needs to pass an offset and length.



 int offset = 10; int length = 24; byte[] cipherText = cipher.doFinal(data, offset, length); 


In this example, the bytes from 10 index and 24 bytes ahead will be encrypted (or decrypted, depending on the initialization of the cipher).



Encryption / Decryption to an existing byte array



All the encryption and decryption examples in this chapter return the encrypted or decrypted data in a new byte array. However, it is also possible to encrypt or decrypt data into an existing byte array. This can be useful for reducing the number of byte arrays created. To do this, transfer the target byte array as a parameter to the update () and / or doFinal () method.



 int offset = 10; int length = 24; byte[] dest = new byte[1024]; cipher.doFinal(data, offset, length, dest); 


In this example, the data is encrypted from 10 index to 24 bytes forward in dest byte array with offset 0. If you want to set a different offset for dest byte array, there are versions update () and doFinal () that accept an additional offset parameter. An example of calling the doFinal () method with an offset in the dest array:



 int offset = 10; int length = 24; byte[] dest = new byte[1024]; int destOffset = 12 cipher.doFinal(data, offset, length, dest, destOffset); 


Cipher instance reuse



Initializing a Cipher instance is an expensive operation and reusing Cipher instances would be a good idea. Fortunately, the Cipher class has been designed for reusability. When you call the doFinal () method for a Cipher instance, it returns to the state it was in immediately after initialization. The Cipher instance can then be used to encrypt or decrypt more data.



An example of a reuse instance of Java Cipher:



 Cipher cipher = Cipher.getInstance("AES"); Key key = ... ///    cipher.init(Cipher.ENCRYPT_MODE, key); byte[] data1 = "abcdefghijklmnopqrstuvwxyz".getBytes("UTF-8"); byte[] data2 = "zyxwvutsrqponmlkjihgfedcba".getBytes("UTF-8"); byte[] cipherText1 = cipher.update(data1); byte[] cipherText2 = cipher.doFinal(data2); byte[] data3 = "01234567890123456789012345".getBytes("UTF-8"); byte[] cipherText3 = cipher.doFinal(data3); 


An instance of Cipher is first created and initialized, and then used to encrypt two blocks of consistent data. Notice the call to update () , and then doFinal () for these two data blocks. After that, the Cipher instance can be re-used to encrypt data. This is done by calling doFinal () with the third data block. After this doFinal () call, you can encrypt another data block with the same instance of Java Cipher.



')

Source: https://habr.com/ru/post/444814/



All Articles