Base64

Base64 is a representation of binary data based on 64 printable characters. Strictly speaking, it’s only one way of coding. Base64 encoding is called Base64 because it uses 64 characters to encode arbitrary data, as well as Base32 and Base16 encoding

Function:

1, because some systems can only use ASCII characters. Base64 is a method used to convert non-ASCII data into ASCII characters. 2. Because this protocol is a text-based protocol, so if the email contains an image, and we know that the image is stored in binary data, not text, we have to encode the binary data into text, Convert invisible ASCII characters to visible characters in Base64

Use:

// Encode - (NSString *)base64EncodedString; { NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];return[data base64EncodedStringWithOptions:0]; } / / decoding - (nsstrings *) base64DecodedString {NSData * data = [[NSData alloc] initWithBase64EncodedString: self options: 0];return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
Copy the code

MD5

MD5(Message digest Algorithm Fifth Edition) is a hash function widely used in computer security field to provide message integrity protection.

Features:

1. Compressibility: For data of any length, the length of the MD5 value calculated is fixed (32 Abstract). 2. Easy to calculate: It is easy to calculate the MD5 value from the original data. 3. Modification resistance: Any change to the original data, even if only 1 byte is changed, the MD5 value obtained is very different. 4. Strong collision resistance (difficult to reverse) : given the original data and its MD5 value, it is very difficult to find a data with the same MD5 value (i.e. forged data).

role

1. Digital signature. When we transmit sensitive information, we can add a unique digital signature for the message by using MD5+ timestamp + salt. To compare the If not consistent The data had been tampered with. 2, document verification, we in the download file, due to the complex network environment, we download the files may have the possibility of content is lost or tampered with. (for example, we obtain the H5 files from the server by JS injection), using MD5 can effectively prevent the occurrence of these things.

The same algorithm

SHA-1:

Resulting in a 160-bit message digest,SHA-1 security has not been accepted in most encryption scenarios since 2000. In 2017, Dutch cryptography research group CWI and Google officially announced that they had cracked SHA-1.

SHA-2:

Released in 2001, including SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256. While there has been no effective attack on SHA-2 so far, its algorithm remains largely similar to SHA-1’s; So some people have started to develop alternative hashing algorithms.

SHA-3:

Officially released in 2015, SHA-3 is not intended to replace SHA-2, which currently has no significant weaknesses. Because of the success of the MD5 hack, as well as the theoretical hack of SHA-0 and SHA-1, NIST felt the need for a different, alternative cryptography hashing algorithm, now known as SHA-3.

implementation

In this case, the hash is performed on a string. In the case of a file, the file stream is read before the hash is performed. Need: an import < CommonCrypto/CommonDigest. H >

MD5

- (NSString *)md5String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), buffer);
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
Copy the code

SHA-1:

- (NSString *)sha1String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}

Copy the code

SHA256:

- (NSString *)sha256String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}
Copy the code

SHA512:

- (NSString *)sha512String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}
Copy the code

SHA3:

Need to download on lot keccak code package: https://github.com/gvanas/KeccakCodePackage

Calculation of large files:

MD5 is used as an example:

#define FileHashDefaultChunkSizeForReadingData 4096- (nsstrings *) fileMD5Hash {/ / open a file to read NSFileHandle * fp = [NSFileHandle fileHandleForReadingAtPath: self].if(fp == nil) {// Null is returned if the path is folder (e.g..framework)returnnil; } // Create the MD5 variable CC_MD5_CTXhashCtx; // Initializes the MD5 variable CC_MD5_Init(&hashCtx);
    
    while(YES) {@autoreleasepool {// Read the file specified length of data, loop to avoid loading into memory too large NSData *data = [fpreadDataOfLength:FileHashDefaultChunkSizeForReadingData]; // Prepare MD5 encryption, upload the content CC_MD5_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
            
            if (data.length == 0) {
                break; }}} // closeFile [fp closeFile]; // Create MD5 result buffer uint8_t buffer[CC_MD5_DIGEST_LENGTH]; // Write MD5 results to buffer CC_MD5_Final(buffer, &)hashCtx); // The raw data is converted to a stringreturn [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];
}
Copy the code

The same is true for other algorithmic file encryption methods, which are provided by the CommonCrypto library.

HMAC Hash calculation (salted)

HMAC is a key-related hash operation message authentication code. HMAC operation uses hash algorithm to generate a message digest as output with a key and a message as input. HMAC is more like an encryption algorithm. It introduces a key, and its security is not entirely dependent on the HASH algorithm used. It is similar to symmetric encryption, but irreversible. Take MD5 as an example:

- (NSString *)hmacMD5StringWithKey:(NSString *)key { const char *keyData = key.UTF8String; const char *strData = self.UTF8String; Uint8_t buffer[CC_MD5_DIGEST_LENGTH]; // Uint8_t buffer[CC_MD5_DIGEST_LENGTH]; // Replace this with other hash functions (e.g. KCCHmacAlgSHA256) CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer); // Switch other hash functions to replace this (e.g. CC_SHA256_DIGEST_LENGTH)return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}
Copy the code

AES(Symmetric encryption)

Introduction to the

The Advanced Encryption Standard (AES) was published by the National Institute of Standards technology in 2001. AES is block-based encryption, that is, the data is processed one block at a time (16 bytes) and filled when the data is not a multiple of 16 bytes. This is called a block cipher (as opposed to bit-based stream ciphers), where 16 bytes is the block length.

AES is relatively easy to implement for fast encryption and decryption in both software and hardware,

implementation

When using AES, you need to configure several encryption parameters. Only when they are consistent, the results on the client and server can be consistent.

Parameter configuration

The key length

The key can be 128, 192, or 256 bits

Encryption scheme

AES is a Block Cipher, which supports several working modes, such as CBC, ECB, CTR, OFB, and CFB.

ECB

AES is a basic encryption method. By default, the CIPHER text is confiscated. The cipher text is divided into blocks of equal length (not complete), encrypted one by one, and output one by one.

CBC

The pattern is chaining, the last one needs to be based on the previous one, and the first one needs to be based on the initialization vector IV. The same input produces different outputs. The data that can be seen is “plaintext +IV” or “plaintext + previous ciphertext”, so plaintext can be hidden.

So encryption/decryption requires: plaintext/ciphertext + secret key + initial vector parameters

Fill the way

Because AES’s algorithm groups plaintext for reprocessing, it requires that each group (16 bytes) be “full,” meaning that the plaintext length must be divisible by 16 bytes.

Therefore, the last group of 16 bytes less than the plaintext should be filled with data first, and the last group of 16 bytes less than the plaintext should be filled with 16 bytes.

CFB,OFB, and CTR modes do not need to fill the last plain text because the encryption operation with the key is the ciphertext after the previous encryption. PKCS7Padding is provided in the iOS SDK.

The initial vector

As introduced in CBC mode, when encryption starts, the starting point is the initial vector, if not set, the system defaults to 0;

code

NSString *const kInitVector = @"Initial vector"; size_t const kKeySize = kCCKeySizeAES256; // key length + (NSData *)encryptAES:(NSData *)content key:(NSString *)key {NSData *contentData = content; NSUInteger dataLength = contentData.length; // Set the encryption key, because the end character of the C string is'\ 0'So size +1 char keyPtr[kKeySize +1]; memset(keyPtr, 0, sizeof(keyPtr)); / / should ensure that size is less than or equal to 16 bytes. [key getCString: keyPtr maxLength: sizeof (keyPtr) encoding: NSUTF8StringEncoding]; // Ciphertext length = plaintext length + secret key length size_t encryptSize = dataLength + kCCBlockSizeAES128; void *encryptedBytes = malloc(encryptSize); // Ciphertext accepts the pointer size_t actualOutSize = 0; / / initialization vector NSData * initVector = [kInitVector dataUsingEncoding: NSUTF8StringEncoding]; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, // kCCOptionPKCS7Padding, //PKCS7Padding keyPtr, // key kKeySize, // key size initvector. bytes, // initial vector contentdata.bytes, // plaintext/ciphertext dataLength, EncryptedBytes, // Result: ciphertext/plaintext buffer encryptSize, // result: ciphertext/plaintext buffer &actualOutSize); // Result pointerif(cryptStatus == kCCSuccess) {// Successfulreturn[NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize]; } // Release free(encryptedBytes);return nil;
}
Copy the code

RSA

The principle of

Mathematical basis

Given any positive integer n, how many positive integers less than or equal to n are mutually prime with n? The function to calculate this value is euler function: for example: φ(8) = 4.

If n is prime then: φ(n) = n-1 principle 3 if n is prime to the n then: φ(p^k) = p^ k-p ^(k-1) if n is the product of two mutually prime integers then: φ(p1 * p2) = φ(p1)φ(p2) principle 1 if positive integers a and N mutually prime then: The remainder of a^φ(n) divided by n is 1 then: a^φ(n) %n=1 Euler’s theorem If positive integers A and p are mutually prime then: A ^p-1 %p=1 fermat’s little theorem If positive integers A and n are mutually prime, then we must find positive integers b such that: ab%n=1, b is the modular inverse element of A. Principle 2

The secret key generated

1, randomly generate two unequal prime numbers p and q, such as P =61 and q=53

2, find the pq product n n=p * q= 61*53=3233.

The length of n is the length of the key. For example, if 3233 is a binary 12 bit key, the length of an RSA key is 1024 bits.

3, to calculate phi (n)

According to principle 1 φ(n) = φ(p)φ(q) = (p-1)(Q-1) = 3120

4, select an integer e at random if 1<e<φ(n) and e and φ(n) are mutually prime

If I choose 17

5. Obtain the modulo inverse element d of e to φ(n)

Ed %φ(n)=1 –> Ed -1 = kφ(n) –> 17d + 3120K =1 a set of integer solutions d=2753 K =-15 can be obtained by extending Euclidean algorithm

6. N and e are public keys and N and D are private keys

Encryption (public key encryption here)

Encrypting plaintext m Note: M is a positive integer, and m must be less than N

M ^e % n = c where c is the encrypted ciphertext 65^17%3233 = 2790 where 2790 is the encrypted ciphertext

N d (decryption)

Decryption principle

Decryption rule: c^d %n = m

Because the encryption process is: m^e % n = c -> c = m^ e-kn to prove the decryption rule is equal to prove (m^e – kn)^d % n = m

(m^e – kn)^d % n = m —> m^ed % n = m

Since we are in step 5 of making public and private keys:

Ed %φ(n)=1 –> Ed = hφ(n)+1

Substitute Ed into the equation to be proved:

M ^ Ed % n = m –> m^hφ(n)+1 % n = m

If M n is mutual

M ^hφ(n)+1 % n = m –> (m^ h (n))^h * m) % n = m

Because euler’s theorem m ^ phi (n) % n = 1 available ((m ^ phi (n)) ^ h * m) % n = m – > (^ 1 h * m) % n = m decryption formula was established

If m n is not mutual

Because step 1 of making the public and private key is n = p * q

Since the encryption method m^e % n = c, and since m<n(this is required at the time of production), c must not be 0, thus m and n are not mutually prime.

Since n is pq and pq is mutual n has only p and q. However, m n has a common factor so the common factor of m n must be an integer multiple of q or P. So m is KP or Kq

Take m= KP for example because the relationship described above is m<n, m n is not coprime, n = qp so k and Q are coprime –> m and Q are coprime

By euler’s theorem: m ^ phi (q) % q = 1 – > due to q for prime Numbers – 1% – > m ^ q q = 1 – > = 1-1% (KP) ^ q q

Because k is interprime with q and P is interprime with Q –> (KP)^q-1 times KP %q = KP

((KP)^h(p-1)(q-1)) * KP)%q = KP because p is prime and h is any integer

By the principle of principle 1 and 3 (((KP) ^ h (p – 1) (q) – 1)) * KP) % q = KP – > (KP) ^ h phi (n) + 1% q = KP

Because Ed % phi (n) = 1, and m = KP so match the h is appropriate is worth (KP) ^ Ed KP – > % q = (m) ^ Ed = tq + m t as an integer.

Divide both sides by m: (m)^ Ed -1 = tq/m +1 Since Ed is an integer and m is an integer, tq/m is an integer. Since q and m are mutually prime, t is an integer multiple of m –> t = yp –> m^ Ed = yn+m –> m^ Ed % n = m

M ^e % n = c –> C ^d % n = m

Security discussion

If you want to break RSA you have to solve for d given n and e because

Because Ed %φ(n)=1, we need to know φ(n) because φ(n)= (p-1)(q-1), so we need to get qp because qp=n, so we need to factor n

And factorization is very difficult especially for very large integers. Because the name text m must be smaller than the key length N, it is often used to encrypt symmetric encryption keys.

The iOS implementation

Use RSA encryption in iOS RSA encryption and decryption in iOS requires **. Der ** and. P12 files.

P12 files are private keys used for encryption. Der files are public keys used for decryption

Add dynamic library security.framework

The specific implementation is too long, I put together a class github link interested can be down to see if it helps you click a Star to encourage a clams ~ this article address blog address