First, encryption algorithm classification
Hash function: not part of the encryption algorithm. For example, MD5 and SHA1/256/512
Symmetric encryption algorithms: DES, 3DES, AES(Advanced cryptography standard, MAC key string is using AES)
Asymmetric encryption algorithm: RAS
1, the Hash
A Hash algorithm transforms an input of arbitrary length into an output of fixed length, which is a Hash value. This translation is a kind of compression mapping, which is the hash value space is usually much smaller than the input space, different input may be hashed into the same output, it is not possible from the hash value to determine the input values, the only simple said is a kind of arbitrary length message down to a fixed length of the message digest function, one of the most famous is the MD5 hash algorithm
Features of Hash:
- The algorithm is public
- The same data, you get the same answer
- Different operations, such as MD5, default to 128 bits, or 32 characters (hexadecimal identifier)
- You can’t reverse it
- Mainly as information summary, information fingerprint, used to do data identification
USES:
- User password encryption: because can not restore, so the encryption is very good, even if the leak, also lunch reverse out of the user’s real password
- Search engine
- copyright
- A digital signature
Password encryption mode:
- Use MD5 directly
- MD5 salt
- HMAC encryption scheme
- Add something
When we need to put the password sent to the server we want to encrypt the password, if we use RSA asymmetric encryption, efficiency is low, and there are potential safety problems, because when through the RSA encryption to decrypt the password will be, and then match, but then the server will need to clear store password, it is not safe:
There are two principles for transferring passwords over the network:
- Users’ private information is not allowed to be transmitted in plain text on the network
- User privacy information cannot be stored in plaintext locally
Therefore, MD5 conversion can be used, so that even if the ciphertext is lost, the user’s original password is unbreakable. Let’s take a look at the MD5 conversion code:
- (NSString *)md5String { const char *str = self.UTF8String; uint8_t buffer[CC_MD5_DIGEST_LENGTH]; CC_MD5(STR, (CC_LONG)strlen(STR), buffer); CC_MD5(STR, (CC_LONG)strlen(STR), buffer) Return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH]; 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 have 123456 encrypted: just get such a hexadecimal string e10adc3949ba59abbe56e057f20f883eCopy the code
However, although MD5 cannot be cracked, the ciphertext corresponding to the same string is unchanged, so we can match the corresponding string through the ciphertext. For example, on CMD5, we can match the common string through the password
After this time we need to string salt on MD5 transformation, the so-called salt is joining together again after a complex string after string of MD5 transformation, but also has a drawback, is that the salt is a fixed must be written procedures, can use brute force, so we can be encrypted by HMAC:
HMAC:
- Encrypt with one key and hash twice
- In real development, the key comes from the server, dynamically
- An account corresponding to a key, and can be updated We under the registration or change the equipment will be the key to the client, and then in the local cache, and then later when landing from the local to the password is encrypted, so we can add a lock equipment, when in equipment need original equipment agreed to landing on new equipment
Apple also offers the CCHmac way:
#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]; }Copy the code
Because every time if we only use MD5 ciphertext, log on every time will lead to log in to the server information is the same, that is dangerous, if hackers hijacked, will be behind time with the request data to understand, then we can add a timestamp (server time), so that each request is different, it doesn’t matter even if hackers hijacked, Because of the delay problem, the timestamp is only accurate to minutes.
- 1. Request the timestamp time from the server to the server before login
- 2. Encrypt the password using HMAC and key on the client to obtain ciphertext 1
- 3. Add the timestamp to ciphertext 1 and encrypt the HMAC and key to obtain ciphertext 2
- 4. Send ciphertext 2 to the server for verification. The server obtains the user password ciphertext (that is, the current time stamp on ciphertext 1) from the local PC and encrypts the HMAC and key to match the ciphertext sent by the client
- If they are different, the system splices ciphertext 1 and the timestamp of the last minute of the server timestamp to match. If they are the same, the system passes. If they are different, the system returns an incorrect password
Search engine:
Get the Hash value for each word, and then these Hash values are added, and then to look up, so no matter how the word you input order, then the content is to find the whole sentence, for example Tom, dick and harry fifty, and the hash value of the three words are the same, and both are 32-bit hexadecimal digits, regardless of where they are before The sum is going to be the same
Copyright:
The original file is Hash calculated to obtain a Hash value. There is a Hash value in the source file. If a pirated file is uploaded to Baidu cloud disk, the Hash value will be incorrect, and some Baidu cloud disk has second transmission, which is because the cloud disk already has the file. The matching Hash shows that the file already exists, so there is no need to upload it again
Digital Signature:
The signature on the check proves that it is yours, so a digital signature is a way of identifying digital information
The client has a payment information, three parties may attack from the middle, tamper with the payment information, so that the customer may pay more money, how to prevent?
- You can convert the payment information into MD5
- The MD5 ciphertext is encrypted with RSA to obtain a ciphertext, which is a digital signature
- After the payment is sent to the server, the server performs RSA decryption on the ciphertext to obtain MD5 ciphertext 1, converts the payment information to MD5 to obtain ciphertext 2, and matches ciphertext 1 and ciphertext 2. If they are the same, the payment information is not modified
Since hash is a 128-bit number regardless of size, there must be some data that yields the same hash value, which is called a hash collision
2, symmetric encryption:
Symmetric encryption means that plaintext can be decrypted using a key to obtain ciphertext, and ciphertext can be decrypted using a key to obtain plaintext
Common algorithms:
- DES: Data Encryption Standard (used sparingly because it is not strong enough)
- 3DES: Encrypts the same data with three keys for three times. This improves the encryption intensity. However, it is troublesome to have three keys and only a few keys are used
- AES: Advanced cryptographic standard, which is used for keychain access and FBI encryption
Xor is generally used for general encryption of game data
Application Mode:
- ECB: Electronic cryptographic mode, each piece of data is encrypted independently. The most basic encryption mode, commonly known as encryption, is that the same plaintext will always be encrypted into the same ciphertext, no initial vector, because each piece of data is separate, so it is vulnerable to password book replay attacks, rarely used
- CBC: grouping password link mode, the use of a key and initialization vector (IV) to perform data encryption, plaintext encrypted with the ciphertext in front of the exclusive or before or after operation and encryption, so as long as the choice of different initial vectors, the same password will form different encrypted cryptograph, this is currently the most widely used model. CBC encrypted cryptograph is context-dependent, but definitely mistakes won’t be passed to the subsequent group, but if a packet loss, the back of the group will be invalid, namely data are associated, behind a piece of data encryption depends on a piece of data before, if one piece of data is destroyed, then the whole data cannot resolve
- CBC effectively ensures the integrity of ciphertext. If a data block is lost or changed during transmission, subsequent data cannot be decrypted
Through terminal command encryption, we will find the introduction of AES terminal encryption and decryption commands:
/ * * * * * DES terminal test instructions (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) * * * $echo -n hello | openssl enc - aes - 128 - CBC - iv 616263-0102030405060708 - K nosalt | base64 (ECB) decryption * $* * DES echo -n HQr0Oij2kbo = | | base64 - D openssl enc - DES - the ECB - 616263 - K nosalt (CBC) - d * * DES declassified * $echo -n alvrvb3Gz88 = | | base64 - d openssl enc - DES - CBC - 0102030405060708 - K iv 616263 - nosalt - d * * AES (ECB) decryption * $echo -n d1QG4T2tivoi0Kiu3NEmZQ = = | | base64 - d openssl enc - AES - 128 - the ECB - 616263 K - nosalt - d * * AES (CBC) decryption * $echo -n u3W/N816uzFpcg6pZ + KBDG = = | base64 - d | openssl enc - AES - 128 - CBC - iv 0102030405060708 -k 616263 -nosalt -d * * tip: * 1> Encryption is first encrypted, then base64 encoding * 2> decryption is first base64 decoding, then decryption */Copy the code
Encryption code:
Encryption and decryption are actually using CCCrypt function, but the type of the incoming is not the same
/** AES - ECB */ NSString * key = @"abc"; NSString * encStr = [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]; NSLog(@" result of encryption: %@",encStr); NSLog(@" Result of decryption: %@",[[EncryptionTools sharedEncryptionTools] decryptString:encStr keyString:key iv:nil]); / * * * / AES - CBC encryption uint8_t iv [8] =,2,3,4,5,6,7,8 {1}; 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 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; / / CBC encryption! } else { option = kCCOptionPKCS7Padding | kCCOptionECBMode; / / the ECB encryption! } / / 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; /**CCCrypt symmetric encryption algorithm of the core function (encryption/decryption) parameters: 1, 2, kCCEncrypt encryption, decryption/kCCDecrypt encryption algorithm, the default / 3 DES, AES encryption mode options kCCOptionPKCS7Padding | kCCOptionECBMode; / / the ECB encryption! kCCOptionPKCS7Padding; / / CBC encryption! 4, encryption key 5, key length 6, iv initialize vector, ECB does not need to specify 7, encrypted data 8, encrypted data length 9, buffer (address), */ CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, sell. 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]; }Copy the code
3. Problems existing in encryption algorithms
For example, we will directly convert the string to be encrypted into NSData and then throw it to the encryption function of the system. However, for hackers, the encrypted function is the function of the system, so hackers can get the data to be encrypted through the function of the hook system, which is very insecure
We can intercept the system function CCCrypt through symbolic breakpoints, because the encrypted data is in the seventh parameter, so we can look at register X6 data