📜 ⬆️ ⬇️

AES encryption and Android client



As they say, nothing foreshadowed trouble. The mobile client was slowly sawed, the coffee was dry, the puzzles were closed one by one, until suddenly a letter arrived at the corporate email:

Urgently introduce new functionality. All the necessary parameters for building a business model, for security purposes, will be transmitted in encrypted form AES / CBC / PKCS5Padding with an AAACCCDDDYYUURRS initialization vector and ZZHHYYTTUUHHGGRR encryption key . An example of encrypted data:
')
p+oJjsGEULNSptP5Sj1BM5w65hMjkqzahORd8ybIkqyJD0V/608c1tYuKIvDLUIa
RQ9jQ6+EwbyMFjlMa6xuEnxOx4sez001hd3NsLO7p00XoTqAvi9zwUBII+
nPphP6Zr0P4icvODpmhlmRILgSBsUf1H/3VN1lNXjo4LTa
GxLqW3VSg9iV9yFq4VMWqsRF

Attempts to quickly search for solutions gave a bunch of non-working examples that showed that the task goes beyond the usual layout of layouts and writing Presenters and requires studying docks and reading manuals. A great opportunity to learn something new and enrich your experience.

But for a start, let's understand what encryption is and why it is needed at all.

A bit of theory about AES encryption


Advanced Encryption Standard (AES) is a symmetric block encryption algorithm adopted by the US government based on the results of the competition as an encryption standard and replacing the less reliable Data Encryption Standard (DES) algorithm . The approved algorithm as a unified encryption standard has become widely used to protect electronic data.

The algorithm is based on substitutions, substitutions and linear transformations, each of which is performed in blocks of 128 bits (digits with values ​​of 0 or 1), which are the basis of the structure of the input and output data, therefore it is called the block cipher. The repetition of operations occurs repeatedly and in the process of each iteration (round) a unique key is calculated based on the encryption key and embedded in further calculations.

The cryptographic key for the AES algorithm is a sequence of 128, 192 or 256 bits. Other input and output parameters and a cryptographic key are not allowed by the AES standard.

The reliability of encryption is ensured by the fact that changing even one block entails changing subsequent blocks and completely changing the final data at the output.

This approach provides high reliability of the algorithm, which can be seen by considering the following simple example:

An example of calculating the time for cracking ciphertext
Table 1: Dependence of the number of combinations on the key length
Key size
Possible number of combinations
1 bit
2
2 bits
four
4 bits
sixteen
8 bit
256
16 bits
65536
32 bits
4.2 * 10 ^ 9
56 bits (DES Algorithm)
7.2 * 10 ^ 16
64 bits
1.8 * 10 ^ 19
128 bits (AES alogrhythm)
3.4 * 10 ^ 38
192 bits (AES alog)
6.2 * 10 ^ 57
256 bits (AES alogrhythm)
1.1 * 10 ^ 77

The fastest supercomputer: 10.51 PetaFlops = 10.51 x 10 ^ 15 Flops (floating point operations per second)

Let the approximate number of operations per second required to test a combination be optimistic: 1000

The number of checks checks per second = (10.51 x 10 ^ 15) / 1000 = 10.51 x 10 ^ 12

The number of seconds in one year = 365 x 24 x 60 x 60 = 31536000

Number of years to crack AES with a 128-bit key = (3.4 x 10 ^ 38) / [(10.51 x 1012) x 31536000] = (0.323 x 10 ^ 26) / 31536000 = 1.02 x 10 ^ 18 = 1 billion billion years.

Based on: How secure is AES against brute force attacks?

A detailed description of the algorithm in English: ADVANCED ENCRYPTION STANDARD
You can also read this wonderful article: How AES works

Initialization vector


Initialization vector (IV) - the initialization vector, is an arbitrary number that can be used along with the secret key to encrypt data.

The use of IV prevents the repetition of data encryption, which makes the hacking process more difficult for a hacker to use a dictionary attack, trying to find patterns and break a cipher. For example, a sequence may appear two or more times in the message body. If the sequences in the encrypted data are repeated, the attacker may assume that the corresponding sequences in the message were also identical. IV prevents the appearance of corresponding repeated sequences of characters in the encrypted text.

Mathematical basis


To remember the study of the mathematical basis, we will use the material from the documentation for the algorithm ADVANCED ENCRYPTION STANDARD , as well as this good material in Russian: General description of the AES cryptoalgorithm

Accordingly, to describe the algorithm, a finite Galois field GF (2 ^ 8) is used, constructed as an extension of the field GF (2) = {0,1} modulo an irreducible polynomial m (x) = x ^ 8 + x ^ 4 + x ^ 3 + x + 1. The elements of the field GF (2 ^ 8) are polynomials of the form

b_7 · x ^ 7 + b_6 · x ^ 6 + b_5 · x ^ 5 + b_4 · x ^ 4 + b_3 · x ^ 3 + b_2 · x ^ 2 + b_1 · x + b_0

Field operations are performed modulo m (x). In total, the field GF (2 ^ 8) has 2 ^ 8 = 256 polynomials.

Basic math operations in the GF field (2 ^ 8)
  1. Adding bytes can be done in any of three ways:
    • to represent the bytes as bit polynomials and add them according to the usual rule of summation of polynomials with the subsequent reduction of the modulus 2 coefficients (XOR operation on the coefficients);
    • modulo 2 add the corresponding bits in bytes;
    • add up bytes in hexadecimal.
  2. Multiplication bytes is performed by presenting them.
    polynomials and multiplication by the usual algebraic rules.
    The resulting product must be reduced modulo the polynomial m (x) = x ^ 8 + x ^ 4 + x ^ 3 + x + 1 (the result of the reduction is equal to the remainder of dividing the product by m (x))
  3. For any non-zero bit polynomial b (x) in the field GF (2 ^ 8)
    there is a polynomial b ^ -1 (x), inverse to it by
    multiplication, i.e. b (x) · b ^ -1 (x) = 1 mod m (x)

Polynomials with coefficients belonging to the field GF (2 ^ 8)
Third degree polynomials with coefficients from a finite
the fields a_i ∈ GF (2 ^ 8) have the form: a (x) = a_3 · x ^ 3 + a_2 · x ^ 2 + a_1 · x + a_0 (1)

Thus, in these polynomials, bytes instead of bits are used as coefficients for unknowns. Further, these polynomials will be represented in the form of the word [a_0, a_1, a_2, a_3]. In the AES standard, when multiplying polynomials of the form (1), the coercion modulo another polynomial x ^ 4 + 1 is used.

To study the arithmetic of the polynomials under consideration, we introduce an additional polynomial b (x) = b_3 · x ^ 3 + b_2 · x ^ 2 + b_1 · x + b_0, where b_i ∈ GF (2 ^ 8). Then
  1. Addition
    a (x) + b (x) = (a_3 ⊕ b_3) x ^ 3 + (a_2 ⊕ b_2) x ^ 2 + (a_1 ⊕ b_1) x + (a_0 b_0)
  2. Multiplication
    To represent the result by a four-byte word, the result is taken modulo a polynomial of degree at most 4. The cipher authors chose for this purpose the polynomial x ^ 4 + 1, for which x_i mod (x ^ 4 + 1) ≡ x_i mod 4 is valid. x ^ 4 + 1 allows you to get the result in the form:

    d (x) = a (x) · b (x) = d_3 · x ^ 3 + d_2 · x ^ 2 + d_1 · x + d_0

Encryption options


Well, there is AES and the initialization vector has become clear. Now we will try to understand the remaining words in the AES / CBC / PKCS5Padding line

Cipher block chaining (CBC) - the ciphertext block concatenation mode is one of the encryption modes for a symmetric block cipher using a feedback mechanism. Each block of plaintext (except the first) is bitwise modulated by 2 with the previous result. One error in the ciphertext block bit affects the decryption of all subsequent blocks. Reorganizing the order of the ciphertext blocks causes damage to the result of the decryption.


Another parameter, PKCS5Padding , indicates how incomplete blocks should be processed. When using one of the general fill algorithms, you need to include the block size in the encrypted data, ensuring that when you try to decrypt the encrypted message, you will receive the required number of bytes.

For all AES encryption settings to work, each implementation of the Java platform must support the following standard encryption algorithms with key sizes (in parentheses):

Standard Cipher transformations
  • AES / CBC / NoPadding (128)
  • AES / CBC / PKCS5Padding (128)
  • AES / ECB / NoPadding (128)
  • AES / ECB / PKCS5Padding (128)
  • DES / CBC / NoPadding (56)
  • DES / CBC / PKCS5Padding (56)
  • DES / ECB / NoPadding (56)
  • DES / ECB / PKCS5Padding (56)
  • DESede / CBC / NoPadding (168)
  • DESede / CBC / PKCS5Padding (168)
  • DESede / ECB / NoPadding (168)
  • DESede / ECB / PKCS5Padding (168)
  • RSA / ECB / PKCS1Padding (1024, 2048)
  • RSA / ECB / OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA / ECB / OAEPWithSHA-256AndMGF1Padding (1024, 2048)


Source: Cipher

Casket just opened



Having dealt with the theory, you can begin to implement the algorithm for decrypting the server message.

Unlike the standard JDK set, for work we need android.util.Base64 to convert the string:

 import android.util.Base64; import java.security.GeneralSecurityException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public static String decrypt(String key, String iv, String encrypted) throws GeneralSecurityException { //      final byte[] keyBytes = key.getBytes(); final byte[] ivBytes = iv.getBytes(); final byte[] encryptedBytes = Base64.decode(encrypted, Base64.DEFAULT); //     SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes)); // final byte[] resultBytes = cipher.doFinal(encryptedBytes); return new String(resultBytes); } 


It is also worth taking into account that the size of the initialization vector should be 16 bytes (128 - bit). This is due to the fact that the AES encryption standard includes three types of block ciphers: AES - 128, AES - 192 and AES - 256. Each of these ciphers has a 128 - bit block size, with key sizes of 128, 192 and 256 bits, respectively. and taking into account the fact that for all types of block cipher, the initialization vector is the same size as the size of the cipher block, we get that the initialization vector is always 128-bit size.

Otherwise, even if we try to use a vector of a different size, the ciphertext will not be decrypted and we will get the following exception:

 java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long 


Result


As can be seen from the implementation, the solution was quite simple and trivial in the context of tasks of this kind. But nevertheless, sometimes it is very useful to delve into the docks and realize what is not so common in the working days of the Android developer.

For the most inquisitive, under the spoiler, what was encrypted in the message:

answer to the problem
 { "items": [ { "name": "star", "color": "green", "id": 21 }, { "name": "dog", "color": "brown", "id": 43 } ], "lucky_item_id": 43 } 

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


All Articles