In cryptography, encryption is mainly divided into symmetric encryption and asymmetric encryption. Asymmetric encryption mainly includes RSA asymmetric encryption (encryption and decryption using public/private keys), and symmetric encryption mainly includes DES/3DES/AES symmetric encryption algorithm. By the way, the Hash algorithm we introduced today is a message digest algorithm. It is not an encryption algorithm, but because of its one-way operation and irreversibility, Hash is a part of the encryption algorithm. Hash algorithms mainly include MD5, Sha1, and Sha2, which have different encryption precision.

So immediately following the previous asymmetric encryption RSA, directly on the dry part of this time

Introduction to symmetric encryption algorithm 4. Terminal commands of symmetric encryption algorithm 5. Terminal Drill of symmetric encryption algorithm 6Copy the code

I. Hash Overview


1. Concept of Hash

A Hash, usually translated as’ Hash ‘or also translated as’ Hash ‘, is a Hash algorithm that transforms an input of any length into a fixed-length output, which is the Hash value. This transformation is a compression mapping, meaning that the space of hashes is usually smaller than the space of inputs, and different inputs may be hashed into the same output, so it is impossible to determine a unique input value from the hash value. Simply put, it is a function that compresses a message of arbitrary length into a message digest of fixed length.

2. Hash features

1. The algorithm is public 2. The result of the same operation is the same 3. For different operations, such as MD5, the default result is 128 bits, 32 characters (hexadecimal identifier). An infinite number of data encryption is a finite number of data, there are one or more data is the same hash value) 5, information, the "fingerprints" of information, is generally used to do data identification (because no inverse operation, generally not used for data encryption, just remove the hash value from the data, and then used to compare, do data identification)Copy the code

3. Hash functions (one-way Hash functions)

Message Digest Algorithm 5 (MD5) 2. Secure Hash Algorithm (SHA) SHA is divided into the following types: SHA SHA - 1-2 series (collectively called SHA - 256 series 2/224256384512512/224512) 3, MAC (Message Authentication Code) 4, CRC (Cyclic Redundancy 5, SM3(domestic hash algorithm)Copy the code

4. Hash usage

1. User password encryption 2. Search engines 3. Copyright 4.Copy the code

5, HMAC

What is HMAC? HMAC(Hash-based Message Authentication Code) is a method that uses the Hash function (one-way Hash function) to construct the message authentication code. The HMAC algorithm takes a key and a message as input and generates a message digest as output. The main purpose is to enable people to verify the correctness of each other’s identity and the validity of the message. The biggest difference with the message digest is that there is a signature key!

HMAC is generated by hashing two different keys twice. There is no known way to create a collision.

There is not just one one-way Hash function used in HMAC, and any high-strength Hash function (one-way Hash function) can be used in HMAC. For example, the HMAC constructed using SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 is named HMAC-SHA1, HMAC-SHA-224, HMAC-SHA-384, and HMAC-SHA-512 respectively.

Digital signature


1. What is digital signature

Digital signature is a method for identifying digital information.

2. Digital signature

The following describes the specific meaning of digital signature in terms of the payment amount of e-commerce:

In the figure, the Hash value of the original commodity information encrypted by RSA is called a digital signature.

Three, symmetric encryption overview


1, symmetric encryption algorithm definition:

Symmetric encryption: The plaintext is encrypted using the key to obtain ciphertext. Ciphertext is decrypted by key to obtain plaintext.

2, symmetric encryption common algorithms

1. Data Encryption Standard (DES) : Data Encryption Standard, which is fast and suitable for encrypting a large amount of Data. 2. 3DES (Triple DES) : it is a symmetric algorithm based on DES. It encrypts the same data three times with three different keys, and the intensity is higher. (Aside: but because of the 3 keys management trouble, so generally not very common ~ a birth died, very sad...) RC2 and RC4: encrypts a large amount of data with variable length keys, which is faster than DES. Advanced Encryption standard, is the next generation of encryption algorithm standard, fast speed, high security level, in the 21st century AES standard is an implementation of Rijndael algorithm; (Side note: It's very secure, Apple uses AES for keychain access, and so does the NSA, making it almost impossible to brute force crack.)Copy the code

There are two main application modes of symmetric encryption, which are introduced in detail below

ECB(Electronic Code Book): Electronic Code Book mode. Each piece of data is encrypted independently.

ECB is the most basic form of encryption, commonly known as encryption, the same plaintext will always be encrypted into the same ciphertext, no initial vector, vulnerable to passbook replay attacks, rarely used in general.

Cipher Block Chaining (CBC) : Cipher Block Chaining mode. Data is encrypted using a key and an initialization vector (IV).

In CBC encryption mode, the plaintext is encrypted after xOR operation with the previous ciphertext. Therefore, the same ciphertext is encrypted after different initial vectors are selected. This is the most widely used ciphertext mode. CBC encrypted ciphertext is context-dependent, but plaintext errors are not passed to subsequent groups, but if one group is lost, all subsequent groups are invalidated (synchronization errors).

CBC effectively ensures the integrity of ciphertext. If a data block is lost or changed during transmission, subsequent data cannot be decrypted.

Symmetric encryption algorithm terminal command


AES Symmetric encryption Algorithm Terminal commands in the two application modes are as follows: 1. Encrypt and decrypt AES(ECB)

AES(ECB) encrypts the ‘battleMage’ string

$ echo -n battleMage | openssl enc -aes-128-ecb -K 616263 -nosalt | base64

Copy the code

AES(ECB) decrypts the ‘battleMage’ string

$ echo -n kXcE5nnetsinAMBEcK6D5g== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d

Copy the code

2, AES(CBC) encryption and decryption

AES(CBC) encrypts the ‘battleMage’ string

$ echo -n battleMage | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64

Copy the code

AES(CBC) decrypts the ‘battleMage’ string

$ echo -n H3tn3dXCEtKNvijJYLsStw== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d

Copy the code

5. Comparison of terminal drills of symmetric encryption algorithms


1. Create a message. TXT file

$ vi message.txt

Copy the code

Press Enter to enter the editing screen, click ‘I’ to enter the editing screen, type 5 rows ‘1234567890’, click ‘Esc ‘, then click’ Shift +:’, enter ‘wq’ and save.

2. Encrypt the ‘message. TXT ‘file directly using AES(ECB), then output a ‘meg1.bin’ file

$ openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out meg1.bin

Copy the code

Just hit Enter to get a meg1.bin file

Then modify message.txt to change the first 1 in the last row to a 2,

Encrypt again with the above command and output a ‘meg2.bin’ file

$ openssl enc -des-ecb -K 616263 -nosalt -in message.txt -out meg2.bin

Copy the code

Just hit Enter to get a meg2.bin file

Next, use XXD to view the meg1.bin and meg2.bin files

Also encrypt ‘message.txt’ with AES(CBC) and output a ‘meg3.bin’ file

$ openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out meg3.bin

Copy the code

TXT again manually edit the message.txt file, restore message.txt, encrypt it with AES(CBC) and output a ‘meg4.bin’ file

$ openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -in message.txt -out meg4.bin
Copy the code

Yeah, like the picture below,

Six, symmetric encryption algorithm code drill


Next start code drill part, need to import a tool class, tool class code is not much, here directly paste the content of tool class, tool class header file AES, DES various terminal commands are also included:

.h files

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>/** * DES(ECB) encryption * $echo- n hello | openssl enc - des - the ECB - 616263 - K nosalt | base64 encryption (CBC) * * * des $echo-n hello | openssl enc - des - 616263-0102030405060708 - K CBC to iv nosalt | base64 AES encryption (ECB) * * * $echo- n hello | openssl enc - aes - 128 - the ECB - 616263 - K nosalt | base64 aes encryption (CBC) * * * $echoThe -n hello | openssl enc - aes - 128-616263-0102030405060708 - K CBC to iv nosalt | base64 * * DES declassified * $(ECB)echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d* * DES(CBC) decryption * $echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d* * AES(ECB) decrypts * $echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d* * AES(CBC) decryption * $echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d*/ @interface EncryptionTools: EncryptionTools: EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: base64 EncryptionTools: NSObject + (instancetype)sharedEncryptionTools; /** @constant kCCAlgorithmAES Advanced Encryption standard, */ @property (Nonatomic, assign) Uint32_t algorithm; /** * encrypt string and return Base64 encoded string ** @param String String to be encrypted * @param keyString Encryption key * @param IV initialization vector (8 bytes) ** @returnReturns the base64 encoded string */ - (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv; /** * decryption string ** @param String Encrypted and Base64 encoded string * @param keyString Decryption key * @param IV initialization vector (8 bytes) ** @returnReturns the decrypted string */ - (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv; @endCopy the code

.m files

#import "EncryptionTools.h"

@interface EncryptionTools()
    @property (nonatomic, assign) int keySize;
    @property (nonatomic, assign) int blockSize;
    @end

@implementation EncryptionTools
    
+ (instancetype)sharedEncryptionTools {
    static EncryptionTools *instance;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
        instance.algorithm = kCCAlgorithmAES;
    });
    
    return instance;
}
    
- (void)setAlgorithm:(uint32_t)algorithm {
    _algorithm = algorithm;
    switch (algorithm) {
        case kCCAlgorithmAES:
        self.keySize = kCCKeySizeAES128;
        self.blockSize = kCCBlockSizeAES128;
        break;
        case kCCAlgorithmDES:
        self.keySize = kCCKeySizeDES;
        self.blockSize = kCCBlockSizeDES;
        break;
        default:
        break; }} - (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {// set the secret key NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding]; uint8_t cKey[self.keySize]; bzero(cKey, sizeof(cKey)); [keyData getBytes:cKey length:self.keySize]; // Set the iv uint8_t cIv[self.blocksize]; bzero(cIv, self.blockSize); int option = 0;if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else{ option = kCCOptionPKCS7Padding | kCCOptionECBMode; } / / set the output buffer NSData * data = [string dataUsingEncoding: NSUTF8StringEncoding]; size_t bufferSize = [data length] + self.blockSize; void *buffer = malloc(bufferSize); Size_t encryptedSize = 0; CCCrypt CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, self.algorithm, option, cKey, self.keySize, cIv, [data bytes], [data length], buffer, bufferSize, &encryptedSize); NSData *result = nil;if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
    } else {
        free(buffer);
        NSLog(@"[error] encryption failure | status code: % d", cryptStatus);
    }
    
    return[result base64EncodedStringWithOptions:0]; } - (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {// sets the secret key NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding]; uint8_t cKey[self.keySize]; bzero(cKey, sizeof(cKey)); [keyData getBytes:cKey length:self.keySize]; // Set the iv uint8_t cIv[self.blocksize]; bzero(cIv, self.blockSize); int option = 0;if (iv) {
        [iv getBytes:cIv length:self.blockSize];
        option = kCCOptionPKCS7Padding;
    } else{ option = kCCOptionPKCS7Padding | kCCOptionECBMode; } / / set the output buffer NSData * data = [[NSData alloc] initWithBase64EncodedString: string options: 0]; size_t bufferSize = [data length] + self.blockSize; void *buffer = malloc(bufferSize); Size_t decryptedSize = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, self.algorithm, option, cKey, self.keySize, cIv, [data bytes], [data length], buffer, bufferSize, &decryptedSize); NSData *result = nil;if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
    } else {
        free(buffer);
        NSLog(@"[error] decryption failure | status code: % d", cryptStatus);
    }
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
    
    @end

Copy the code

Next, create a new project, drag the tool class. H,.m into the project, and implement the touchBegin method in viewController.m

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSString * key = @"abc"; Uint8_t iv [8] =,2,3,4,5,6,7,8 {1}; / / note: If you select AES(CBC), the initial vector iv will pass nil directly. If you select AES(CBC), the initial vector IV will need to pass the value. NSString * encStr = [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:nil];
    
    NSLog(@"AES(ECB) encryption results in: %@", encStr);
    NSLog(@"AES(ECB) decryption result: %@", [[EncryptionTools sharedEncryptionTools]decryptString:encStr keyString:key iv:nil]); //2, select AES(CBC) NSData * ivData = [NSData dataWithBytes:iv length:sizeof(iv)]; NSString * encStr1 = [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:ivData];
    
    NSLog(@"AES(CBC) encryption results in: %@", encStr1);
    NSLog(@"AES(CBC) decryption result: %@", [[EncryptionTools sharedEncryptionTools]decryptString:encStr1 keyString:key iv:ivData]);
    
}


@end


Copy the code

Click Run and the result is OK

CryptDemo[1790:115503] AES(ECB) encryption result CryptDemo[1790:115503] AES(ECB) decrypt result: CryptDemo[1790:115503] AES(CBC) encryption result: CryptDemo[1790:115503] AES(CBC) decrypt result: HelloCopy the code

CCCrypt function


Step 6 is used to encapsulate good encryption tool class EncryptionTools. J h, this is a utility class encapsulates the CCCrypt function, let’s study the core functions of encryption tools CCCrypt function:

To use CCCrypt, you need to introduce system libraries

#import <CommonCrypto/CommonCrypto.h>

Copy the code

Whether encryption or decryption is to use this function, the following we introduce the parameters of this function, parameter explanation I directly note in the back of the API, pay attention to the pit inside!!

1, CCOperation op: operation type: encryption or decryption, enumeration value; KCCEncrypt indicates encryption. KCCDecrypt indicates decryption. CCAlgorithm ALG: encryption algorithm. KCCAlgorithmDES Advanced Encryption Standard, 128-bit (default) Attention attention !!!!!!!!!! There's a pit here; KCCOptionPKCS7Padding stands for fill mode. The options must be filled mode. CCCrypt's option is CBC by default, so you only need to add a fill mode to represent CBC; But the ECB requires an additional plus a kCCOptionECBMode, so choose the ECB requires kCCOptionPKCS7Padding | kCCOptionECBMode; So to select CBC and ECB, click below! kCCOptionPKCS7Padding; On behalf of the CBC kCCOptionPKCS7Padding | kCCOptionECBMode; Const void *iv: initializing vector; const void *dataIn: initializing vector; const void *dataIn: initializing vector; Size_t dataInLength: specifies the length of the encrypted data. 9. Void *dataOut: specifies the memory address of the encrypted ciphertext. Size of the encrypted ciphertext buffer 11. Size_t *dataOutMoved CCCryptorStatus CCCrypt(CCOperation op, /* kCCEncrypt, etc. */ CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */ CCOptions options, /* kCCOptionPKCS7Padding, etc. */ const void *key, size_t keyLength, const void *iv, /* optional initialization vector */ const void *dataIn, /* optional per op and alg */ size_t dataInLength, void *dataOut, /* data RETURNED here */ size_t dataOutAvailable, size_t *dataOutMoved)Copy the code

It is important to note that using this function directly is very dangerous. Because of this function is the system to provide, no matter you are encryption or decryption, is called the CCCrypt function, and hackers can escape mobile phones the debug or is prison break re-signed debugging, can use function breakpoint is broken into your CCCrypt function, corresponding parameters, and then directly obtained through the register function according to the above function, Const void *dataIn = const void *dataIn = const void *dataIn = const void *dataIn = const void *dataIn = const void *dataIn Specific operations are as follows:

1, or open the previous project, set the function breakpoint CCCrypt, and use the real machine to run!! You have to use the real machine because the real machine has a different CPU than the emulator

2. Run the project, simulate hacker debugging, and then click on the screen to start touchBegin, and then the breakpoint stops at CCCrypt

3, because the function is called, are in the CPU register, input register to view instructions

register read x6

Copy the code

Read x6 is the seventh argument to read the function, the first being x0

4, get the address, and then strong type, circle it, your data is leaked

Therefore, this function can not be directly used, now only say the basic, later will talk about security protection in detail ~ today said here ~