swift DES-ECB 加密解密仅供参考
2020-04-02 本文已影响0人
舟_e9ce
记录一下DES-ECB加密解密。
加密解密用到的工具NSData+DataToString.h
@interface NSData (DataToString)
-(NSString *)convertedToUtf8String;
- (NSData *)replaceNoUtf8:(NSData *)data;
- (NSString *)hexStringFromData:(NSData *)myD;
@end
NSData+DataToString.m
@implementation NSData (DataToString)
-(NSString *)convertedToUtf8String{
NSString *string = [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
if (string == nil) {
string = [[NSString alloc] initWithData:[self UTF8Data] encoding:NSUTF8StringEncoding];
}
return string;
}
-(NSData *)UTF8Data {
//保存结果
NSMutableData *resData = [[NSMutableData alloc] initWithCapacity:self.length];
NSData *replacement = [@"12" dataUsingEncoding:NSUTF8StringEncoding];
uint64_t index = 0;
const uint8_t *bytes = self.bytes;
long dataLength = (long) self.length;
while (index < dataLength) {
uint8_t len = 0;
uint8_t firstChar = bytes[index];
// 1个字节
if ((firstChar & 0x80) == 0 && (firstChar == 0x09 || firstChar == 0x0A || firstChar == 0x0D || (0x20 <= firstChar && firstChar <= 0x7E))) {
len = 1;
}
// 2字节
else if ((firstChar & 0xE0) == 0xC0 && (0xC2 <= firstChar && firstChar <= 0xDF)) {
if (index + 1 < dataLength) {
uint8_t secondChar = bytes[index + 1];
if (0x80 <= secondChar && secondChar <= 0xBF) {
len = 2;
}
}
}
// 3字节
else if ((firstChar & 0xF0) == 0xE0) {
if (index + 2 < dataLength) {
uint8_t secondChar = bytes[index + 1];
uint8_t thirdChar = bytes[index + 2];
if (firstChar == 0xE0 && (0xA0 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
len = 3;
} else if (((0xE1 <= firstChar && firstChar <= 0xEC) || firstChar == 0xEE || firstChar == 0xEF) && (0x80 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
len = 3;
} else if (firstChar == 0xED && (0x80 <= secondChar && secondChar <= 0x9F) && (0x80 <= thirdChar && thirdChar <= 0xBF)) {
len = 3;
}
}
}
// 4字节
else if ((firstChar & 0xF8) == 0xF0) {
if (index + 3 < dataLength) {
uint8_t secondChar = bytes[index + 1];
uint8_t thirdChar = bytes[index + 2];
uint8_t fourthChar = bytes[index + 3];
if (firstChar == 0xF0) {
if ((0x90 <= secondChar & secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
len = 4;
}
} else if ((0xF1 <= firstChar && firstChar <= 0xF3)) {
if ((0x80 <= secondChar && secondChar <= 0xBF) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
len = 4;
}
} else if (firstChar == 0xF3) {
if ((0x80 <= secondChar && secondChar <= 0x8F) && (0x80 <= thirdChar && thirdChar <= 0xBF) && (0x80 <= fourthChar && fourthChar <= 0xBF)) {
len = 4;
}
}
}
}
// 5个字节
else if ((firstChar & 0xFC) == 0xF8) {
len = 0;
}
// 6个字节
else if ((firstChar & 0xFE) == 0xFC) {
len = 0;
}
if (len == 0) {
index++;
[resData appendData:replacement];
} else {
[resData appendBytes:bytes + index length:len];
index += len;
}
}
return resData;
}
//注意:如果是三字节utf-8,第二字节错误,则先替换第一字节内容(认为此字节误码为三字节utf8的头),然后判断剩下的两个字节是否非法;
- (NSData *)replaceNoUtf8:(NSData *)data
{
char aa[] = {'A','A','A','A','A','A'}; //utf8最多6个字符,当前方法未使用
NSMutableData *md = [NSMutableData dataWithData:data];
int loc = 0;
while(loc < [md length])
{
char buffer;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0x80) == 0)
{
loc++;
continue;
}
else if((buffer & 0xE0) == 0xC0)
{
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80)
{
loc++;
continue;
}
loc--;
//非法字符,将这个字符(一个byte)替换为A
[md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
loc++;
continue;
}
else if((buffer & 0xF0) == 0xE0)
{
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80)
{
loc++;
[md getBytes:&buffer range:NSMakeRange(loc, 1)];
if((buffer & 0xC0) == 0x80)
{
loc++;
continue;
}
loc--;
}
loc--;
//非法字符,将这个字符(一个byte)替换为A
[md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
loc++;
continue;
}
else
{
//非法字符,将这个字符(一个byte)替换为A
[md replaceBytesInRange:NSMakeRange(loc, 1) withBytes:aa length:1];
loc++;
continue;
}
}
return md;
}
//data转换为十六进制的string
- (NSString *)hexStringFromData:(NSData *)myD{
Byte *bytes = (Byte *)[myD bytes];
//下面是Byte 转换为16进制。
NSString *hexStr=@"";
for(int i=0;i<[myD length];i++)
{
NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16进制数
if([newHexStr length]==1)
hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
else
hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
}
NSLog(@"hex = %@",hexStr);
return hexStr;
}
@end
字符串转NSData,系统自带的不好用,会出现解密后数据为空,(我这里用的时候是这样的)
此方法可以单独去封装只是一个工具,借鉴别的大神的,用在获取到后台返回数据后,解密前
// MARK: 获取到的字符串转成NSData
- (NSData *)convertHexStrToData:(NSString *)str {
if (!str || [str length] == 0) {
return nil;
}
NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
NSRange range;
if ([str length] % 2 == 0) {
range = NSMakeRange(0, 2);
} else {
range = NSMakeRange(0, 1);
}
for (NSInteger i = range.location; i < [str length]; i += 2) {
unsigned int anInt;
NSString *hexCharStr = [str substringWithRange:range];
NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
[scanner scanHexInt:&anInt];
NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
[hexData appendData:entity];
range.location += range.length;
range.length = 2;
}
NSLog(@"hexdata: %@", hexData);
return hexData;
}
封装后调用方法
// MARK: 加密
static func encrypotion(key:String,content:String) -> String {
let keyString = key
let keyData : NSData! = (keyString.data(using: String.Encoding.utf8)! as NSData)
let message = content
let data:NSData! = (message.data(using: String.Encoding.utf8)! as NSData)
print("要加密的字符串:" + message)
// 下边时进行加密解密的代码
// let result:NSData? = data.AES128Crypt(operation: CCOperation(kCCEncrypt), keyData: keyData)
// print("encrypt = \(result!)")
// let oldData = result?.AES128Crypt(operation: CCOperation(kCCDecrypt), keyData: keyData)
// print("decrypt = \(oldData!)")
// print(String(data: oldData as! Data, encoding: String.Encoding.utf8)!)
// 下边是进行加密的数据
let enData = data.enCrypt(algorithm: .DES, keyData: keyData)
let str = enData.hexString(from: enData as Data)
return str
}
// MARK: 解密
static func decryption(key:String, enData:String) -> [String:Any] {
let keyString = key
let keyData : NSData! = (keyString.data(using: String.Encoding.utf8)! as NSData)
let nsData : NSData = DesECB().convertHexStr(toData: enData) as NSData
// 下边是进行解密的数据
let deData : NSData = nsData.deCrypt(algorithm: .DES, keyData: keyData)!
print("解析数据 \(String(data: deData as Data, encoding: String.Encoding.utf8)!)")
if let dict = try? JSONSerialization.jsonObject(with: deData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : Any] {
print(dict)
return dict!
}
return [:]
}
加密解密具体方法 swift 版
import UIKit
enum CryptoAlgorithm {
case AES,AES128,DES,DES3,CAST,RC2,RC4,Blowfish
var algorithm : CCAlgorithm {
var result : UInt32 = 0
switch self {
case .AES:
result = UInt32(kCCAlgorithmAES)
case .AES128:
result = UInt32(kCCAlgorithmAES128)
case .DES:
result = UInt32(kCCAlgorithmDES)
case .DES3:
result = UInt32(kCCAlgorithm3DES)
case .CAST:
result = UInt32(kCCAlgorithmCAST)
case .RC2:
result = UInt32(kCCAlgorithmRC2)
case .RC4:
result = UInt32(kCCAlgorithmRC4)
case .Blowfish:
result = UInt32(kCCAlgorithmBlowfish)
}
return CCAlgorithm(result)
}
var keyLength : Int {
var result : Int = 0
switch self {
case .AES:
result = kCCKeySizeAES128
case .AES128:
result = kCCKeySizeAES256
case .DES:
result = kCCKeySizeDES
case .DES3:
result = kCCKeySize3DES
case .CAST:
result = kCCKeySizeMaxCAST
case .RC2:
result = kCCKeySizeMaxRC2
case .RC4:
result = kCCKeySizeMaxRC4
case .Blowfish:
result = kCCKeySizeMaxBlowfish
}
return Int(result)
}
var cryptLength:Int {
var result:Int = 0
switch self {
case .AES:
result = kCCKeySizeAES128
case .AES128:
result = kCCBlockSizeAES128
case .DES:
result = kCCBlockSizeDES
case .DES3:
result = kCCBlockSize3DES
case .CAST:
result = kCCBlockSizeCAST
case .RC2:
result = kCCBlockSizeRC2
case .RC4:
result = kCCBlockSizeRC2
case .Blowfish:
result = kCCBlockSizeBlowfish
}
return Int(result)
}
}
extension NSData {
/**
加密
- parameter algorithm:加密方式
- parameter keyData:加密key
- return NSData :加密后的数据
*/
func enCrypt(algorithm:CryptoAlgorithm,keyData:NSData) -> NSData {
return crypt(algorithm: algorithm, operation: CCOperation(kCCEncrypt), keyData: keyData)!
}
/// 解密
/// - Parameters:
/// - algorithm: 解密方式
/// - keyData: 解密key
func deCrypt(algorithm:CryptoAlgorithm,keyData:NSData) -> NSData? {
return crypt(algorithm: algorithm, operation: CCOperation(kCCDecrypt), keyData: keyData)
}
func crypt(algorithm:CryptoAlgorithm,operation:CCOperation,keyData:NSData) -> NSData? {
let keyBytes = keyData.bytes
let keyLength = Int(algorithm.keyLength)
let datalength = self.length
let dataBytes = self.bytes
let cryptLength = Int(datalength + algorithm.cryptLength)
let cryptPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: cryptLength)
let algoritm: CCAlgorithm = CCAlgorithm(algorithm.algorithm)
let option: CCOptions = CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding)
let numBytesEncrypted = UnsafeMutablePointer<Int>.allocate(capacity: 1)
numBytesEncrypted.initialize(to: 0)
let cryptStatus = CCCrypt(operation, algoritm, option, keyBytes, keyLength, nil, dataBytes, datalength, cryptPointer, cryptLength, numBytesEncrypted)
// 判断是否加密成功
if CCStatus(cryptStatus) == CCStatus(kCCSuccess) {
let len = Int(numBytesEncrypted.pointee)
let data:NSData = NSData(bytesNoCopy: cryptPointer, length: len)
numBytesEncrypted.deallocate()
return data
} else {
numBytesEncrypted.deallocate()
cryptPointer.deallocate()
return nil
}
}
}