
1. Classification of Encryption Algorithms
1. Hash
-
The algorithm is public
-
For the same data, the result is the same
-
For different data operations, such as MD5, the result is by default 128 bits, which is 32 characters (hexadecimal representation)
-
Cannot be reversed
-
Mainly used as information summary, information fingerprint, for data identification
-
Encryption of user passwords: Because it cannot be restored, the encryption is very good; even if leaked, the real user password cannot be reversed
-
Search engines
-
Copyright
-
Digital signatures
-
Directly using MD5
-
MD5 with salt
-
HMAC encryption scheme
-
Add some complexity
-
Plaintext transmission of user’s private information is not allowed over the network
-
Plaintext storage of user’s private information is not allowed locally
- (NSString *)md5String {
const char *str = self.UTF8String;
uint8_t buffer[CC_MD5_DIGEST_LENGTH];
// Pass the string pointer, the length of the string, and the space to store the ciphertext; the space is generally 16 bytes, and after encryption, the ciphertext will be stored in hexadecimal format in the space,
CC_MD5(str, (CC_LONG)strlen(str), buffer);
// After obtaining the ciphertext, we concatenate it to get a ciphertext string
return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
NSMutableString *strM = [NSMutableString string];
for (int i = 0; i < length; i++) {
[strM appendFormat:"%02x", bytes[i]];
}
return [strM copy];
}
We encrypt 123456: we get this hexadecimal string
e10adc3949ba59abbe56e057f20f883e

HMAC:
-
Uses a key for encryption and performs hashing twice
-
In actual development, the key comes from the server and is dynamic
-
One account corresponds to one key, and it can also be updated. When we register or change devices, we send the key to the client, which caches it locally. Then, each time we log in, we retrieve it locally to encrypt the password. This way, we can add a device lock, requiring consent from the original device to log in on a new device.
#pragma mark - HMAC Hash Function
- (NSString *)hmacMD5StringWithKey:(NSString *)key {
const char *keyData = key.UTF8String;
const char *strData = self.UTF8String;
uint8_t buffer[CC_MD5_DIGEST_LENGTH];
CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
-
1. Before logging in, request the server’s timestamp
-
2. Then, on the client side, encrypt the password using HMAC and the key to obtain ciphertext 1
-
3. Concatenate ciphertext 1 with the timestamp and perform another HMAC and key encryption to obtain ciphertext 2
-
4. Send ciphertext 2 to the server for verification. The server retrieves the stored user password ciphertext (ciphertext 1 concatenated with the current timestamp) and performs HMAC and key encryption to match it with the ciphertext sent from the client. If they match, verification is successful.
-
If they do not match, concatenate ciphertext 1 with the timestamp from one minute prior to the server’s timestamp and match again. If they match, it passes; if not, it returns that the password is incorrect.
Search Engines:
Copyright:
Digital Signatures:
-
Convert the payment information into MD5
-
Then perform RSA encryption on the MD5 ciphertext to obtain a ciphertext, which is the digital signature.
-
After passing it to the server, the server decrypts the ciphertext with RSA to obtain MD5 ciphertext 1, converts the payment information into MD5 to obtain ciphertext 2, and then matches ciphertext 1 and ciphertext 2. If they are the same, it means the payment information has not been modified.
2. Symmetric Encryption:
-
DES: Data Encryption Standard (used less because its strength is insufficient)
-
3DES: Uses three keys to perform three encryptions on the same data, enhancing strength, but using three keys is cumbersome, so it is used less.
-
AES: Advanced Encryption Standard, used for keychain access, also used by the FBI for encryption.
-
ECB: Electronic Codebook mode, each block of data is encrypted independently. The most basic encryption mode, meaning that the same plaintext will always be encrypted into the same ciphertext without an initialization vector. Since each block of data is independent, it is vulnerable to password replay attacks and is rarely used in practice.
-
CBC: Cipher Block Chaining mode, uses a key and an initialization vector (IV) to perform encryption on the data. The plaintext is XORed with the previous ciphertext before encryption, so by choosing different initialization vectors, the same password will produce different ciphertext. This is currently the most widely used mode. The ciphertext generated by CBC is contextually related, but errors in plaintext will not propagate to subsequent blocks. However, if one block is lost, all subsequent blocks will be invalid, meaning that the data is all interconnected. The encryption and decryption of the subsequent data block depend on the previous data block. If one block is damaged, the entire data cannot be parsed.
-
CBC can effectively ensure the integrity of the ciphertext. If a data block is lost or altered during transmission, subsequent data will be unable to decrypt properly.
/**
* Terminal test commands
*
* DES(ECB) encryption
* $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
*
* DES(CBC) encryption
* $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* AES(ECB) encryption
* $ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
*
* AES(CBC) encryption
* $ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* DES(ECB) decryption
* $ 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) decryption
* $ 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
*
* Note:
* 1> The encryption process is to encrypt first, then base64 encode
* 2> The decryption process is to first base64 decode, then decrypt
*/
Encryption Code:
/** AES - ECB */
NSString * key = @"abc";
NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil];
NSLog(@"The result of encryption is: %@", encStr);
NSLog(@"The result of decryption is: %@", [[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:nil]);
/** AES - CBC encryption */
uint8_t iv[8] = {1,2,3,4,5,6,7,8};
NSData * ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
NSLog(@"CBC encryption: %@", [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:@"abc" iv:ivData]);
NSLog(@"Decryption: %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"u3W/N816uzFpcg6pZ+kbdg==" keyString:key iv:ivData]);
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
// Set the key
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t cKey[self.keySize];
bzero(cKey, sizeof(cKey));
[keyData getBytes:cKey length:self.keySize];
// Set 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 output buffer
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
size_t bufferSize = [data length] + self.blockSize;
void *buffer = malloc(bufferSize);
// Start encryption
size_t encryptedSize = 0;
// Encryption and decryption both use this -- 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 failed | Status code: %d", cryptStatus);
}
return [result base64EncodedStringWithOptions:0];
}
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
// Set the key
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t cKey[self.keySize];
bzero(cKey, sizeof(cKey));
[keyData getBytes:cKey length:self.keySize];
// Set iv
uint8_t cIv[self.blockSize];
bzero(cIv, self.blockSize);
int option = 0;
if (iv) {
[iv getBytes:cIv length:self.blockSize];
option = kCCOptionPKCS7Padding; // CBC encryption!
} else {
option = kCCOptionPKCS7Padding | kCCOptionECBMode; // ECB encryption!
}
// Set output buffer
NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
size_t bufferSize = [data length] + self.blockSize;
void *buffer = malloc(bufferSize);
// Start decryption
size_t decryptedSize = 0;
/** CCCrypt is the core function of symmetric encryption algorithm (encryption/decryption)
Parameters:
1. kCCEncrypt for encryption / kCCDecrypt for decryption
2. Encryption algorithm, default AES/DES
3. Encryption option
kCCOptionPKCS7Padding | kCCOptionECBMode; // ECB encryption!
kCCOptionPKCS7Padding; // CBC encryption!
4. Encryption key
5. Key length
6. iv initialization vector, ECB does not need to specify
7. Data to be encrypted
8. Length of the data to be encrypted
9. Buffer (address) to store the ciphertext
10. Size of the buffer
11. Size of the encryption result
*/
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 failed | Status code: %d", cryptStatus);
}
return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
3. Problems with Encryption Algorithms

Author | iOS_BigBook Link | Click the lower left “Read Original” to enter the author’s homepage
-End-
Recently, some friends asked me to help find some interview questions materials, so I rummaged through my collection of 5T materials and compiled them. It can be said to be essential for programmer interviews! All materials have been organized into a cloud storage, welcome to download!
<strong>Interview Questions</strong>
γ to get itLook here for more good contentShare good articles with more peopleββ