歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C#/iOS/Android通用加密解密方法

公司在做移動端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才能正常的解密。

Copyright © Linux教程網 All Rights Reserved