公司在做移动端ios/android,服务器提供接口使用的.net,用到加密解密这一块,也在网上找了一些方法,有些是.net加密了android解密不了,或者反之。下面的是三个平台都可以加密解密的方法。加密解密中用到的key="1234578";在调取方法时传值即可。
C#代码
#region 跨平台加解密(c#) /// <summary> /// 对字符串进行DES加密 /// </summary> /// <param name="sourceString">待加密的字符串</param> /// <returns>加密后的BASE64编码的字符串</returns> public string Encrypt(string sourceString, string sKey) { byte[] btKey = Encoding.UTF8.GetBytes(sKey); byte[] btIV = Encoding.UTF8.GetBytes(sKey); DESCryptoServicePRovider des = new DESCryptoServiceProvider(); using (MemoryStream ms = new MemoryStream()) { byte[] inData = Encoding.UTF8.GetBytes(sourceString); try { using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write)) { cs.Write(inData, 0, inData.Length); cs.FlushFinalBlock(); } return Convert.ToBase64String(ms.ToArray()); } catch { throw; } } } /// <summary> /// 解密 /// </summary> /// <param name="pToDecrypt">要解密的以Base64</param> /// <param name="sKey">密钥,且必须为8位</param> /// <returns>已解密的字符串</returns> public string Decrypt(string pToDecrypt, string sKey) { //转义特殊字符 pToDecrypt = pToDecrypt.Replace("-", "+"); pToDecrypt = pToDecrypt.Replace("_", "/"); pToDecrypt = pToDecrypt.Replace("~", "="); byte[] inputByteArray = Convert.FromBase64String(pToDecrypt); using (DESCryptoServiceProvider des = new DESCryptoServiceProvider()) { des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); des.IV = ASCIIEncoding.ASCII.GetBytes(sKey); System.IO.MemoryStream ms = new System.IO.MemoryStream(); using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); cs.Close(); } string str = Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); return str; } } #endregion
IOS代码
static const char* encryptWithKeyAndType(const char *text,CCOperation encryptOperation,char *key){ NSString *textString=[[NSString alloc]initWithCString:text encoding:NSUTF8StringEncoding]; // NSLog(@"[[item.url description] UTF8String=%@",textString); const void *dataIn; size_t dataInLength; if (encryptOperation == kCCDecrypt)//传递decrypt 解码 { //解码 base64 NSData *decryptData = [GTMBase64 decodeData:[textString dataUsingEncoding:NSUTF8StringEncoding]];//转utf-8并decode dataInLength = [decryptData length]; dataIn = [decryptData bytes]; } else //encrypt { NSData* encryptData = [textString dataUsingEncoding:NSUTF8StringEncoding]; dataInLength = [encryptData length]; dataIn = (const void *)[encryptData bytes]; } CCCryptorStatus ccStatus; uint8_t *dataOut = NULL; //理解位type/typedef 缩写(效维护代码比:用int用long用typedef定义) size_t dataOutAvailable = 0; //size_t 操作符sizeof返结类型 size_t dataOutMoved = 0; dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1); dataOut = malloc( dataOutAvailable * sizeof(uint8_t)); memset((void *)dataOut, 00, dataOutAvailable);//已辟内存空间buffer首 1 字节值设值 0 //NSString *initIv = @"12345678"; const void *vkey = key; const void *iv = (const void *) key; //[initIv UTF8String]; //CCCrypt函数 加密/解密 ccStatus = CCCrypt(encryptOperation,// 加密/解密 kCCAlgorithmDES,// 加密根据哪标准(des3desaes) kCCOptionPKCS7Padding,// 选项组密码算(des:每块组加密 3DES:每块组加三同密) vkey, //密钥 加密解密密钥必须致 kCCKeySizeDES,// DES 密钥(kCCKeySizeDES=8) iv, // 选初始矢量 dataIn, // 数据存储单元 dataInLength,// 数据 (void *)dataOut,// 用于返数据 dataOutAvailable, &dataOutMoved); NSString *result = nil; if (encryptOperation == kCCDecrypt)//encryptOperation==1 解码 { //解密data数据改变utf-8字符串 result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:NSUTF8StringEncoding]; } else //encryptOperation==0 (加密程加密数据转base64) { //编码 base64 NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved]; result = [GTMBase64 stringByEncodingData:data]; } return [result UTF8String]; }+(NSString*)encryptWithContent:(NSString*)content type:(CCOperation)type key:(NSString*)aKey{ const char * contentChar =[content UTF8String]; char * keyChar =(char*)[aKey UTF8String]; const char *miChar; miChar = encryptWithKeyAndType(contentChar, type, keyChar); return [NSString stringWithCString:miChar encoding:NSUTF8StringEncoding];}
Android代码
//加密 public static String DecryptDoNet(String message, String key) throws Exception { byte[] bytesrc = Base64.decode(message.getBytes(), Base64.DEFAULT); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8")); cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); byte[] retByte = cipher.doFinal(bytesrc); return new String(retByte); } // 解密 public static String EncryptAsDoNet(String message, String key) throws Exception { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8")); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] encryptbyte = cipher.doFinal(message.getBytes()); return new String(Base64.encode(encryptbyte, Base64.DEFAULT)); }
最后还要注意一下,一般在客户端调用接口时,请求的是URL地址,参数需要加密,比如token,如果token里含有+号,URL会转码为空格,这时在.net端接收到token时,需要把token中的空格替换为+号:token = Regex.Replace(token, @"/s", "+");这样接收到的token才能正常的解密。
新闻热点
疑难解答