3DES加解密

2021-03-26  本文已影响0人  江河_ios

.h

#import <Foundation/Foundation.h>

@interface EncryptAndDecrypt3DES : NSObject

/**
 *  3DES加密(使用64位转码)
 *
 *  @param  plainText  要加密的字符串(如果要加密的是非字符串,要先转为json字符串)
 *  @param  key        密钥
 *  @param  iv         加密时用的偏移字符串
 *  @return 返回加密之后的字符串
 */
 + (NSString*)encrypt:(NSString*)plainText key:(NSString *)key iv:(NSString *)iv;

/**
 *  3DES解密(使用64位转码)
 *
 *  @param  encryptText 要解密的字符串(此加密字符串为64位转码之后)
 *  @param  key         密钥
 *  @param  iv          加密时用的偏移字符串
 *  @return 返回解密之后的字符串(根据情况可为json字符串)
 */
+ (NSString*)decrypt:(NSString*)encryptText key:(NSString *)key iv:(NSString *)iv;

@end

.m

#import "EncryptAndDecrypt3DES.h"
#import <CommonCrypto/CommonCryptor.h>
static const char CRDEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

@implementation EncryptAndDecrypt3DES
//加密方法
+ (NSString*)encrypt:(NSString*)plainText key:(NSString *)key iv:(NSString *)iv {
   NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
   size_t plainTextBufferSize = [data length];
   const void *vplainText = (const void *)[data bytes];
   
   CCCryptorStatus ccStatus;
   uint8_t *bufferPtr = NULL;
   size_t bufferPtrSize = 0;
   size_t movedBytes = 0;
   
   bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
   bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
   memset((void *)bufferPtr, 0x0, bufferPtrSize);
   
   const void *vkey = (const void *) [key UTF8String];
   const void *vinitVec = (const void *) [iv UTF8String];
   
   ccStatus = CCCrypt(kCCEncrypt,
                      kCCAlgorithm3DES,
                      kCCOptionPKCS7Padding,
                      vkey,
                      kCCKeySize3DES,
                      vinitVec,
                      vplainText,
                      plainTextBufferSize,
                      (void *)bufferPtr,
                      bufferPtrSize,
                      &movedBytes);
   
   NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
//    NSString *result = [NSString crd_base64EncodedStringFrom:myData];
   NSString *result = [self dataToBase64String:myData];
   result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
   free(bufferPtr);
   return result;
}

// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText key:(NSString *)key iv:(NSString *)iv {
   NSData *encryptData = [self base64StringToData:encryptText];
   size_t plainTextBufferSize = [encryptData length];
   const void *vplainText = [encryptData bytes];
   
   CCCryptorStatus ccStatus;
   uint8_t *bufferPtr = NULL;
   size_t bufferPtrSize = 0;
   size_t movedBytes = 0;
   
   bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
   bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
   memset((void *)bufferPtr, 0x0, bufferPtrSize);
   
   const void *vkey = (const void *) [key UTF8String];
   const void *vinitVec = (const void *) [iv UTF8String];
   
   ccStatus = CCCrypt(kCCDecrypt,
                      kCCAlgorithm3DES,
                      kCCOptionPKCS7Padding,
                      vkey,
                      kCCKeySize3DES,
                      vinitVec,
                      vplainText,
                      plainTextBufferSize,
                      (void *)bufferPtr,
                      bufferPtrSize,
                      &movedBytes);
   
   NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
                                                                    length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] ;
   return result;
}

+ (NSString *)dataToBase64String:(NSData *)data
{
   if ([data length] == 0)
       return @"";

   char *characters = malloc((([data length] + 2) / 3) * 4);
   if (characters == NULL)
       return nil;
   NSUInteger length = 0;

   NSUInteger i = 0;
   while (i < [data length])
   {
       char buffer[3] = {0,0,0};
       short bufferLength = 0;
       while (bufferLength < 3 && i < [data length])
           buffer[bufferLength++] = ((char *)[data bytes])[i++];

       //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
       characters[length++] = CRDEncodingTable[(buffer[0] & 0xFC) >> 2];
       characters[length++] = CRDEncodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
       if (bufferLength > 1)
           characters[length++] = CRDEncodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
       else characters[length++] = '=';
       if (bufferLength > 2)
           characters[length++] = CRDEncodingTable[buffer[2] & 0x3F];
       else characters[length++] = '=';
   }

   return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
}

+ (NSData *)base64StringToData:(NSString *)string
{
   if (string == nil)
       return nil;
   if ([string length] == 0)
       return [NSData data];

   static char *decodingTable = NULL;
   if (decodingTable == NULL)
   {
       decodingTable = malloc(256);
       if (decodingTable == NULL)
           return nil;
       memset(decodingTable, CHAR_MAX, 256);
       NSUInteger i;
       for (i = 0; i < 64; i++)
           decodingTable[(short)CRDEncodingTable[i]] = i;
   }

   const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
   if (characters == NULL)     //  Not an ASCII string!
       return nil;
   char *bytes = malloc((([string length] + 3) / 4) * 3);
   if (bytes == NULL)
       return nil;
   NSUInteger length = 0;

   NSUInteger i = 0;
   while (YES)
   {
       char buffer[4];
       short bufferLength;
       for (bufferLength = 0; bufferLength < 4; i++)
       {
           if (characters[i] == '\0')
               break;
           if (isspace(characters[i]) || characters[i] == '=')
               continue;
           buffer[bufferLength] = decodingTable[(short)characters[i]];
           if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!
           {
               free(bytes);
               return nil;
           }
       }

       if (bufferLength == 0)
           break;
       if (bufferLength == 1)      //  At least two characters are needed to produce one byte!
       {
           free(bytes);
           return nil;
       }
       //  Decode the characters in the buffer to bytes.
       bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
       if (bufferLength > 2)
           bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
       if (bufferLength > 3)
           bytes[length++] = (buffer[2] << 6) | buffer[3];
   }
   bytes = realloc(bytes, length);
   return [NSData dataWithBytesNoCopy:bytes length:length];
}




@end
上一篇 下一篇

猜你喜欢

热点阅读