Common encryption methods in the project base64, AES, MD5, sha-1, base64sha-1
Today, I reorganized several encryption methods that were frequently used in previous projects, we found that we didn't really understand these encryption methods in the past. First of all, from the nature of encryption, it is to output some data with an indefinite length according to certain encoding rules as a data string of a certain length. This is what I understand. Different encryption methods adopt different encoding rules. Before reading this article, you should first understand some basic concepts:
1. Simple concept
Plaintext: the information before encryption
Ciphertext: Confidential Information
Algorithms: encryption or decryption algorithms
Key: The key used by the algorithm (read as miyao, correct should be miyue, but everyone reads miyao)
2. Simple Example
Add 1 to each number of 123456 and get 234567,
123456 is the plaintext, 234567 is the ciphertext, And the encryption key is 1. the encryption algorithm is
3. symmetric encryption and asymmetric encryption
For example,
123456 --> 234567 of the encryption key is 1, and the encryption algorithm is for each +
234567 --> 123456 the decryption key is also 1, and the decryption algorithm is for each-
The encryption algorithm (+) and the decryption algorithm (-) are called symmetric encryption,
Likewise, asymmetric encryption is called an asymmetric encryption algorithm.
4. algorithm example
Symmetric encryption algorithms: DES algorithm, 3DES algorithm, TDEA algorithm, Blowfish algorithm, RC5 algorithm, IDEA algorithm, and AES algorithm.
Asymmetric encryption algorithms: RSA, Elgamal, backpack algorithm, Rabin, D-H, and ECC.
Typical hash algorithms: MD2, MD4, MD5, and SHA-1 (the objective is to convert any long input to fixed long output by using the algorithm, and ensure that the input changes have different outputs, and cannot be decrypted in reverse mode)
Next, let's talk about our common encryption methods.
1. base64: This encryption method is commonly used in some projects. Generally, this encryption method is very good for cracking. Its actual function of encryption is not to keep it confidential. You can see the BASE64 encoded string, all are composed of regular characters on the standard keyboard. Therefore, the encoded string is transmitted between gateways and will not generate a UNICODE string that cannot be identified or lost. After studying the EMAIL carefully, you will find that the EMAIL is actually sent after base64 encoding. And then restore it when receiving the message.
In other cases, BASE64 encoding is also good, such as an image file or any other binary file. I can encode it into a string. In this way, XML or database can be used to store these files directly in text mode.
Let's talk about his specific use:
First, you need to add several files GTMBase64. This is a third-party library that can be obtained from network resources and directly calls the algorithms in it.
// Encryption Algorithm
+ (NSData *) encodeData :( NSData *) data {
Return [self baseEncode: [data bytes]
Length: [data length]
Charset: kBase64EncodeChars
Padded: YES];
}
// Decryption algorithm
+ (NSData *) decodeData :( NSData *) data {
Return [self baseDecode: [data bytes]
Length: [data length]
Charset: kBase64DecodeChars
RequirePadding: YES];
}
From the program, we can see that no matter whether it is encryption or decryption, the objects it processes are nsdata type.
Therefore, we need to perform binary encoding on the data before encryption and decryption.
Instance description:
// User Name
NSData * data_user = [userName_TF.text dataUsingEncoding: NSUTF8StringEncoding];
NSData * Data_U = [GTMBase64 encodeData: data_user];
NSString * username = [[NSString alloc] initWithData: Data_U encoding: NSUTF8StringEncoding];
2. The following describes the functions and usage of MD5 encryption.
First, we need to know the principle and nature of MD5 encryption. MD5 is a secure algorithm with two features. First, the input two segments of plain text, that is, the original data, will not get the same output value.
Second, the process is irreversible, that is, the original plaintext cannot be obtained based on the output value. Therefore, there is no ready-made Algorithm for decryption of MD5. We can only use the exhaustive method to scatter the plaintext that may appear with the MD5 algorithm, form a one-to-one ing table between the obtained hash value and the original data. In the so-called decryption, The ing table is used to find the corresponding original plaintext.
There is absolutely no algorithm. You can calculate the original plaintext by outputting the encrypted hash value.
Algorithm used:
-(NSString *) md5Encrypt {
Const char * cStr = [self UTF8String];
Unsigned char result [16];
CC_MD5 (cStr, strlen (cStr), result );
Return [NSString stringWithFormat: @ "% 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X % 02X ",
Result [0], result [1], result [2], result [3],
Result [4], result [5], result [6], result [7],
Result [8], result [9], result [10], result [11],
Result [12], result [13], result [14], result [15]
];
}
Directly expand the NSString algorithm and directly call this algorithm to make it easy to use.
[Nsstring md5Encrypt]-> the returned value is also a string. MD5 encryption can generate a 16-bit string or a 32-Bit String.
3. Both SHA-1 and MD5 are digest algorithms and are irreversible algorithms;
In terms of application, applicability is more important than security. The two algorithms have different lengths: SHA-1 160 bits and MD5 128 bits.
If the digest is signed after the digest is calculated from the security perspective, the anti-denial and anti-tampering capabilities can be increased.
// 32-bit MD5 Encryption
+ (NSString *) getMd5_32Bit_String :( NSString *) srcString isUppercase :( BOOL) isUppercase {
Const char * cStr = [srcString UTF8String];
Unsigned char digest [CC_MD5_DIGEST_LENGTH];
CC_MD5 (cStr, strlen (cStr), digest );
NSMutableString * result = [NSMutableString stringWithCapacity: CC_MD5_DIGEST_LENGTH * 2];
For (int I = 0; I <CC_MD5_DIGEST_LENGTH; I ++)
[Result appendFormat: @ "% 02x", digest [I];
If (isUppercase ){
Return [result uppercaseString];
} Else {
Return result;
}
}
// 16-bit MD5 Encryption
+ (NSString *) getMd5_16Bit_String :( NSString *) srcString isUppercase :( BOOL) isUppercase {
// Extract the middle 16 bits of the 32-bit MD5 Hash
NSString * md5_32Bit_String = [self getMd5_32Bit_String: srcString isUppercase: NO];
NSString * result = [[md5_32Bit_String substringToIndex: 24] substringFromIndex: 8]; // 9 ~ 25-digit
If (isUppercase ){
Return [result uppercaseString];
} Else {
Return result;
}
}
// Sha1 Encryption Method
+ (NSString *) getSha1String :( NSString *) srcString {
Const char * cstr = [srcString cStringUsingEncoding: NSUTF8StringEncoding];
NSData * data = [NSData dataWithBytes: cstr length: srcString. length];
Uint8_t digest [CC_SHA1_DIGEST_LENGTH];
CC_SHA1 (data. bytes, data. length, digest );
NSMutableString * result = [NSMutableString stringWithCapacity: CC_SHA1_DIGEST_LENGTH * 2];
For (int I = 0; I <CC_SHA1_DIGEST_LENGTH; I ++ ){
[Result appendFormat: @ "% 02x", digest [I];
}
Return result;
}
// Sha256 Encryption Method
+ (NSString *) getSha256String :( NSString *) srcString {
Const char * cstr = [srcString cStringUsingEncoding: NSUTF8StringEncoding];
NSData * data = [NSData dataWithBytes: cstr length: srcString. length];
Uint8_t digest [CC_SHA256_DIGEST_LENGTH];
CC_SHA1 (data. bytes, data. length, digest );
NSMutableString * result = [NSMutableString stringWithCapacity: CC_SHA256_DIGEST_LENGTH * 2];
For (int I = 0; I <CC_SHA256_DIGEST_LENGTH; I ++ ){
[Result appendFormat: @ "% 02x", digest [I];
}
Return result;
}
// Sha384 Encryption Method
+ (NSString *) getSha384String :( NSString *) srcString {
Const char * cstr = [srcString cStringUsingEncoding: NSUTF8StringEncoding];
NSData * data = [NSData dataWithBytes: cstr length: srcString. length];
Uint8_t digest [CC_SHA384_DIGEST_LENGTH];
CC_SHA1 (data. bytes, data. length, digest );
NSMutableString * result = [NSMutableString stringWithCapacity: CC_SHA384_DIGEST_LENGTH * 2];
For (int I = 0; I <CC_SHA384_DIGEST_LENGTH; I ++ ){
[Result appendFormat: @ "% 02x", digest [I];
}
Return result;
}
// Sha512 Encryption Method
+ (NSString *) getSha512String :( NSString *) srcString {
Const char * cstr = [srcString cStringUsingEncoding: NSUTF8StringEncoding];
NSData * data = [NSData dataWithBytes: cstr length: srcString. length];
Uint8_t digest [CC_SHA512_DIGEST_LENGTH];
CC_SHA512 (data. bytes, data. length, digest );
NSMutableString * result = [NSMutableString stringWithCapacity: CC_SHA512_DIGEST_LENGTH * 2];
For (int I = 0; I <CC_SHA512_DIGEST_LENGTH; I ++)
[Result appendFormat: @ "% 02x", digest [I];
Return result;
}
This is a specific algorithm, which is directly encapsulated in a class and called directly. It can be used in the same way as MD5.
4. AES encryption algorithm.
AES is an evolutionary version of DES.
This is a confidential encryption algorithm that I currently use. This encryption requires a key value to be decrypted and the same key value to be decrypted, which is equivalent to a password.
Encryption Algorithm usage
// Used for key encryption and decryption
# Define kCryptingKey @ "1102130405061708" // same as above
# Define kCryptingIv @ "1102130405061708" // same as above
@ Implementation Tool
+ (NSString *) encrypt :( NSString *) recource
{
NSData * data = [recource dataUsingEncoding: NSUTF8StringEncoding];
NSData * result = [self AES128EncryptWithKey: kCryptingKey withData: data iv: kCryptingIv];
Return [self stringWithHexBytes: result];
}
+ (NSString *) decryptData :( NSData *) recource
{
NSData * decrypt = [self AES128DecryptWithKey: kCryptingKey withData: recource iv: kCryptingIv];
Return [[NSString alloc] initWithData: decrypt encoding: NSUTF8StringEncoding];
}
+ (NSString *) decrypt :( NSString *) recource
{
NSData * data = [self decodeFromHexidecimal: recource];
NSData * decrypt = [self AES128DecryptWithKey: kCryptingKey withData: data iv: kCryptingIv];
Return [[NSString alloc] initWithData: decrypt encoding: NSUTF8StringEncoding];
}
+ (NSData *) decodeFromHexidecimal :( NSString *) str
{
NSString * command = [NSString stringWithString: str];
Command = [command stringByReplacingOccurrencesOfString: @ "" withString: @ ""];
NSMutableData * commandToSend = [[NSMutableData data] init];
Unsigned char whole_byte;
Char byte_chars [3] = {'\ 0',' \ 0', '\ 0 '};
Int I;
For (I = 0; I <[command length]/2; I ++ ){
Byte_chars [0] = [command characterAtIndex: I * 2];
Byte_chars [1] = [command characterAtIndex: I * 2 + 1];
Whole_byte = strtol (byte_chars, NULL, 16 );
[CommandToSend appendBytes: & whole_byte length: 1];
}
Return commandToSend;
}
+ (NSData *) AES128EncryptWithKey :( NSString *) key withData :( NSData *) _ data iv :( NSString *) iv
{
Char keyPtr [kCCKeySizeAES128 + 1];
Memset (keyPtr, 0, sizeof (keyPtr ));
[Key getCString: keyPtr maxLength: sizeof (keyPtr) encoding: NSUTF8StringEncoding];
Char ivPtr [kCCBlockSizeAES128 + 1];
Memset (ivPtr, 0, sizeof (ivPtr ));
[Iv getCString: ivPtr maxLength: sizeof (ivPtr) encoding: NSUTF8StringEncoding];
NSUInteger dataLength = [_ data length];
Int diff = kCCKeySizeAES128-(dataLength % kCCKeySizeAES128 );
Unsigned long int newSize = 0;
If (diff> 0)
{
NewSize = dataLength + diff;
}
Char dataPtr [newSize];
Memcpy (dataPtr, [_ data bytes], [_ data length]);
For (int I = 0; I <diff; I ++)
{
DataPtr [I + dataLength] = 0x00;
}
Size_t bufferSize = newSize + kCCBlockSizeAES128;
Void * buffer = malloc (bufferSize );
Memset (buffer, 0, bufferSize );
Size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt (kCCEncrypt, kCCAlgorithmAES128, 0x0000,
KeyPtr, kmeaneysizeaes128,
IvPtr,
DataPtr,
Sizeof (dataPtr ),
Buffer, bufferSize,/* output */
& NumBytesEncrypted );
If (cryptStatus = kCCSuccess)
{
// The returned NSData takes ownership of the buffer and will free it on deallocation
Return [NSData dataWithBytesNoCopy: buffer length: numBytesEncrypted];
}
Free (buffer); // free the buffer
Return nil;
}
+ (NSData *) AES128DecryptWithKey :( NSString *) key withData :( NSData *) data iv :( NSString *) iv
{
Char keyPtr [kCCKeySizeAES128 + 1];
Memset (keyPtr, 0, sizeof (keyPtr ));
[Key getCString: keyPtr maxLength: sizeof (keyPtr) encoding: NSUTF8StringEncoding];
Char ivPtr [kCCBlockSizeAES128 + 1];
Memset (ivPtr, 0, sizeof (ivPtr ));
[Iv getCString: ivPtr maxLength: sizeof (ivPtr) encoding: NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
Size_t bufferSize = dataLength + kCCBlockSizeAES128;
Void * buffer = malloc (bufferSize );
Size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt (kCCDecrypt, kCCAlgorithmAES128, 0x0000,
KeyPtr, kCCBlockSizeAES128,
IvPtr,
[Data bytes],
DataLength,
Buffer, bufferSize,/* output */
& NumBytesDecrypted );
If (cryptStatus = kCCSuccess ){
// The returned NSData takes ownership of the buffer and will free it on deallocation
Return [NSData dataWithBytesNoCopy: buffer length: numBytesDecrypted];
}
Free (buffer); // free the buffer;
Return nil;
}
+ (NSString *) stringWithHexBytes :( NSData *) _ data {
NSMutableString * stringBuffer = [NSMutableString stringWithCapacity :( [_ data length] * 2)];
Const unsigned char * dataBuffer = [_ data bytes];
Int I;
For (I = 0; I <[_ data length]; ++ I ){
[StringBuffer appendFormat: @ "% 02lX", (unsigned long) dataBuffer [I];
}
Return [stringBuffer copy];
}
It can also be directly encapsulated in a class to directly call the algorithm, in general, during encryption, the project's development document will tell you that you only need to replace the corresponding part of the key here.
5. RSA to be updated