多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现

行是知之始,知是行之成。这篇文章主要讲述多语言(Java& C#& Ruby& C++& Objective-C& Android)互通的TripleDES加解密算法实现相关的知识,希望能为你提供帮助。
直入主题;前段时间根据公司对开发API的安全性要求,采用了小数据加密验证的方式,根据需求采用了三重DES加密算法。在实施的过程中发现各个语言之间加密由于加密补位的方式有所不同,导致不同语言之间加密之后无法相互解析。在强大的会联网技术和公司其他同事的支持下,最终整合了集java,C#,Ruby,C++,Objective-C,android多语言的可以互通的TripleDES加密算法,虽然在AES加密推崇的今天DES有些乏力,但小可大胆贴上代码,希望能给大家提供一些思路。
Java DES加密(Java只提供了加密算法)
【多语言(Java& C#& Ruby& C++& Objective-C& Android)互通的TripleDES加解密算法实现】 

多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现

文章图片
多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现

文章图片
/** * 密钥算法 */ private static final String KEY_ALGORITHM = "DESede/ECB/PKCS5Padding"; /** * 加密/解密算法 工作模式 填充模式 */ ; private static final String CIPHER_ALGORITHM = "DESede"; public final static String secretKey = "密钥"; private final static String encoding = "utf-8"; /** * 3DES加密 * * @param plainText *普通文本 * @return */ public static String encode(String plainText, String key) {System.out.println("plainText------" + plainText); System.out.println("key------" + key); byte[] keyByte = Base64.decode(key); byte[] plain = null; try { plain = plainText.getBytes("UTF-8"); byte[] input = encrypt(plain, keyByte); //System.out.println("base64的结果"+Base64.toBase64String(input)); //System.out.println("tostring结果:"+input.toString()); return Base64.toBase64String(input); //return Base64.toBase64String(input); } catch (Exception e) { e.printStackTrace(); } return ""; }/** * 密钥转换 * * @param key * @return * @throws Exception */ private static Key toKey(byte[] key) throws Exception { // 实例化3DES密钥 SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM); return secretKey; }/** * 加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encrypt(byte[] data, byte[] key) throws Exception { // 还原密钥 Key k = toKey(key); // 实例化 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); // 用密钥初始化cipher对象 cipher.init(Cipher.ENCRYPT_MODE, k); // 执行加密操作 return cipher.doFinal(data); }

View Code 
C# DES加密/解密
 
1 /// < summary> 2 /// TripleDES 加密 3 /// < /summary> 4 /// < param name="toEncrypt"> < /param> 5 /// < param name="privateKey"> < /param> 6 /// < returns> < /returns> 7 private static string DesEncrypt(string toEncrypt, string key) { 8var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); 9var keyArray = Convert.FromBase64String(key); 10TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider { 11Key = keyArray, 12Mode = CipherMode.ECB, 13Padding = PaddingMode.PKCS7 14}; 15ICryptoTransform cTransform = tdes.CreateEncryptor(); 16byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 17tdes.Clear(); 18return Convert.ToBase64String(resultArray, 0, resultArray.Length); 19 } 20 /// < summary> 21 /// TripleDES解密 22 /// < /summary> 23 /// < param name="toDecrypt"> < /param> 24 /// < param name="privateKey"> < /param> 25 /// < returns> < /returns> 26 public static string DesDecrypt(string toDecrypt, string key) { 27try { 28//先base64解密 因为加密的时候最后走了一道base64加密 29var enBytes = Convert.FromBase64String(toDecrypt); 30var keyArray = Convert.FromBase64String(key); 31TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider { 32Key = keyArray, 33Mode = CipherMode.ECB, 34Padding = PaddingMode.PKCS7 35}; 36 37ICryptoTransform cTransform = tdes.CreateDecryptor(); 38byte[] resultArray = cTransform.TransformFinalBlock(enBytes, 0, enBytes.Length); 39tdes.Clear(); 40 41return Encoding.UTF8.GetString(resultArray); 42} catch { 43return ""; 44} 45 }

 
Ruby DES加解密
Ruby加密使用了第三方库(openssl)
CIPHER_MODEL = ‘DES-EDE3‘def des_encrypt(to_encrypt, key) key = Base64.decode64(key) cipher = OpenSSL::Cipher::Cipher.new(CIPHER_MODEL) cipher.encrypt cipher.key = key cipher.padding = 1 encrypted = cipher.update(to_encrypt) + cipher.final data = https://www.songbingjia.com/android/Base64.encode64(encrypted) data.gsub!("\n", ‘‘) enddef des_decrypt(to_decrypt, key) str = Base64.decode64(to_decrypt) key = Base64.decode64(key) des = OpenSSL::Cipher::Cipher.new(CIPHER_MODEL) des.decrypt des.key = key des.padding = 1 result = des.update(str) # result < < des.final result.force_encoding(‘ISO-8859-1‘).encode(‘UTF-8‘) # [result].pack(‘H*‘).force_encoding(‘ISO-8859-1‘).encode(‘UTF-8‘) end

C++ DES加解密实现
多语言(Java&amp;C#&amp;Ruby&amp;C++&amp;Objective-C&amp;Android)互通的TripleDES加解密算法实现

文章图片
多语言(Java&amp;C#&amp;Ruby&amp;C++&amp;Objective-C&amp;Android)互通的TripleDES加解密算法实现

文章图片
1 int base64_decode(const unsigned char *in_str, int in_len, unsigned char *out_str) 2 { 3BIO *b64, *bio; 4/*BUF_MEM *bptr = NULL; */ 5/*int counts; */ 6int size = 0; 7 8if (in_str == NULL || out_str == NULL) 9return -1; 10 11b64 = BIO_new(BIO_f_base64()); 12BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 13 14bio = BIO_new_mem_buf(in_str, in_len); 15bio = BIO_push(b64, bio); 16 17size = BIO_read(bio, out_str, in_len); 18out_str[size] = ‘\0‘; 19 20BIO_free_all(bio); 21return size; 22 } 23 24 25 // OpenSSL Base64编码 26 size_t Base64Encode(const unsigned char *strCipher, size_t length, bool newLine, unsigned char* strBase64Cipher) 27 { 28size_t len = 0; 29BIO *bmem = NULL; 30BIO *b64 = NULL; 31BUF_MEM *bptr; 32 33b64 = BIO_new(BIO_f_base64()); 34if (!newLine) { 35BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 36} 37bmem = BIO_new(BIO_s_mem()); 38b64 = BIO_push(b64, bmem); 39BIO_write(b64, strCipher, length); 40BIO_flush(b64); 41BIO_get_mem_ptr(b64, & bptr); 42BIO_set_close(b64, BIO_NOCLOSE); 43 44unsigned char *encBuff = (unsigned char *)malloc(bptr-> length + 1); 45memcpy(encBuff, bptr-> data, bptr-> length); 46encBuff[bptr-> length] = 0; 47BIO_free_all(b64); 48 49len = strlen((const char*)encBuff); 50for (size_ti = 0; i < len; i++) 51{ 52*(strBase64Cipher + i) = encBuff[i]; 53} 54 55free(encBuff); 56return len; 57 } 58 59 // OpenSSL Base64解码 60 unsigned char* Base64Decode(const unsigned char *strHex, size_t length, bool newLine/*, unsigned char *strDec*/) 61 { 62/*size_t len = 0; */ 63BIO *b64 = NULL; 64BIO *bmem = NULL; 65unsigned char *decBuffer = (unsigned char *)malloc(length); 66memset(decBuffer, 0, length); 67b64 = BIO_new(BIO_f_base64()); 68if (!newLine) { 69BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 70} 71bmem = BIO_new_mem_buf(strHex, length); 72bmem = BIO_push(b64, bmem); 73BIO_read(bmem, decBuffer, length); 74BIO_free_all(bmem); 75 76/*len = strlen((const char*)decBuffer); 77for (size_t i = 0; i < len; i++) 78{ 79*(strDec + i) = decBuffer[i]; 80} 81 82free(decBuffer); */ 83return decBuffer; 84 } 85 86 87 // 3DES-ECB加密 88 size_t Encrypt3DES_ECB(const unsigned char *strPlain, size_t pLen, unsigned char *strHexKey, unsigned char *strHexIV, unsigned char *strBase64Cipher) 89 { 90unsigned char* decKey = NULL; 91unsigned char* decIV = NULL; 92unsigned char strCipher[500] = {0}; 93 94decKey = Base64Decode(strHexKey, 32, 0); 95if (strHexIV) 96{ 97decIV = Base64Decode(strHexIV, 32, 0); 98} 99 100size_t cLen = 0; 101size_t temp = 0; 102//初始化密码算法结构体 103EVP_CIPHER_CTX ctx; 104EVP_CIPHER_CTX_init(& ctx); 105// 加密初始化,设置加密模式为:3DES-ECB,并将密钥转换为内部密钥形式 106EVP_EncryptInit_ex(& ctx, 107EVP_des_ede3_ecb(), 108NULL, 109decKey, 110decIV); 111free(decKey); 112free(decIV); 113 114// 对strPlain进行加密 115if (!EVP_EncryptUpdate(& ctx, strCipher, & cLen, strPlain, pLen)) 116{ 117EVP_CIPHER_CTX_cleanup(& ctx); 118return 0; 119} 120// 加密ctx的buffer中余下的数据 121if (!EVP_EncryptFinal_ex(& ctx, strCipher + cLen, & temp)) 122{ 123EVP_CIPHER_CTX_cleanup(& ctx); 124return 0; 125} 126 127cLen += temp; 128EVP_CIPHER_CTX_cleanup(& ctx); 129Base64Encode(strCipher, cLen, 0, strBase64Cipher); 130return cLen; 131 } 132 133 134 // 3DES-ECB解密 135 size_t Decrypt3DES_ECB(const unsigned char *strCipher, size_t cLen, unsigned char *strHexKey, unsigned char *strHexIV, unsigned char *strPlain, size_t pLen) 136 { 137int size = 0; 138unsigned char* decKey = NULL; 139unsigned char* decIV = NULL; 140/*unsigned char* decCipher = NULL; */ 141unsigned char decCipher[500] = { 0 }; 142 143decKey = Base64Decode(strHexKey, 32, 0); 144if (strHexIV) 145{ 146decIV = Base64Decode(strHexIV, 32, 0); 147} 148 149/*decCipher = Base64Decode(strCipher, cLen, 0); */ 150 151size = base64_decode(strCipher, cLen, decCipher); 152 153size_t temp = 0; 154//初始化密码算法结构体 155EVP_CIPHER_CTX ctx; 156EVP_CIPHER_CTX_init(& ctx); 157// 解密初始化,设置解密模式为:3DES-ECB,并将密钥转换为内部密钥形式 158EVP_DecryptInit_ex(& ctx, EVP_des_ede3_ecb(), NULL, decKey, decIV); 159// 对cipher进行解密 160if (!EVP_DecryptUpdate(& ctx, strPlain, & pLen, decCipher, size)) 161{ 162EVP_CIPHER_CTX_cleanup(& ctx); 163return 0; 164} 165 166// 解密ctx的buffer中余下的数据 167if (!EVP_DecryptFinal_ex(& ctx, strPlain + pLen, & temp)) 168{ 169EVP_CIPHER_CTX_cleanup(& ctx); 170return 0; 171} 172 173pLen += temp; 174strPlain[pLen] = ‘\0‘; 175EVP_CIPHER_CTX_cleanup(& ctx); 176 177free(decKey); 178free(decIV); 179/*free(decCipher); */ 180return pLen; 181 }

View CodeObj-c 加密实现
1 //Des加密 2 NSString *yw_encryptUseDES(NSString *plainText, NSString *key){ 3NSData *keyData = [GTMBase64 decodeString:key]; 4NSString *ciphertext = nil; 5NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; 6NSUInteger dataLength = [textData length]; 7NSMutableData* outputData = [NSMutableData dataWithLength:(textData.length + kCCBlockSize3DES)]; 8size_t outLength; 9CCCryptorStatus result = CCCrypt(kCCEncrypt,// CCOperation op 10kCCAlgorithm3DES,// CCAlgorithm alg 11kCCOptionPKCS7Padding | kCCOptionECBMode, // CCOptions options 12keyData.bytes,// const void *key 13keyData.length,// size_t keyLength 14nil,// const void *iv 15textData.bytes,// const void *dataIn 16dataLength,// size_t dataInLength 17outputData.mutableBytes,// void *dataOut 18outputData.length,// size_t dataOutAvailable 19& outLength); 20 21if (result != kCCSuccess) 22return nil; 23 24[outputData setLength:outLength]; 25ciphertext = [GTMBase64 stringByEncodingData:outputData]; 26return ciphertext; 27 }

Android实现代码:Android和Java差不多,上面Java代码缺少解密实现,加密的可以参考此处
多语言(Java&amp;C#&amp;Ruby&amp;C++&amp;Objective-C&amp;Android)互通的TripleDES加解密算法实现

文章图片
多语言(Java&amp;C#&amp;Ruby&amp;C++&amp;Objective-C&amp;Android)互通的TripleDES加解密算法实现

文章图片
1 /** 2* 密钥算法 3*/ 4 private static final String KEY_ALGORITHM = "DESede"; 5 /** 6* 加密/解密算法工作模式填充模式 7*/ 8 // private static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding"; 9 private static final String CIPHER_ALGORITHM = "DESede/ECB/PKCS7Padding"; 10 /** 11* 密钥转换 12* @param key 13* @return 14* @throws Exception 15*/ 16 private static Key toKey(byte[] key) throws Exception{ 17//实例化3DES密钥 18SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM); 19return secretKey; 20 } 21 22 /** 23* 加密 24* @param data 25* @param key 26* @return 27* @throws Exception 28*/ 29 public static byte[] encrypt(byte[] data, byte[] key) throws Exception{ 30//还原密钥 31Key k = toKey(key); 32//实例化 33Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 34//初始化 35cipher.init(Cipher.ENCRYPT_MODE, k); 36//执行操作 37return cipher.doFinal(data); 38 } 39 40 /** 41* 解密操作 42* @param data 43* @param key 44* @return 45* @throws Exception 46*/ 47 public static byte[] decrypt(byte[] data, byte[] key) throws Exception{ 48//还原密钥 49Key k = toKey(key); 50//实例化 51Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 52//初始化 53cipher.init(Cipher.DECRYPT_MODE, k); 54//执行操作 55return cipher.doFinal(data); 56 } 57 58 /** 59* 初始化密钥 60* @return 61* @throws Exception 62*/ 63 public static byte[] initKey() throws Exception{ 64//实例化KeyGenerator 65KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); 66//初始化 67keyGenerator.init(168); 68//生成密钥 69SecretKey secretKey = keyGenerator.generateKey(); 70//返回密钥 71return secretKey.getEncoded(); 72 } 73 /** 74* --------------------------------------------------------------- 75* 加密调用 76* --------------------------------------------------------------- 77*/ 78 // 加解密统一使用的编码方式 79 private final static String encoding = "utf-8"; 80 81 /** 82* 3DES加密 83* 84* @param plainText 普通文本 85* @return 86* @throws Exception 87*/ 88 public static String encode(String plainText) { 89 90byte[] keyByte = Base64.decode(secretKey, Base64.NO_WRAP); 91byte[] plain = null; 92try { 93plain = plainText.getBytes("UTF-8"); 94byte[] input = DESedeUtil.encrypt(plain, keyByte); 95return Base64.encodeToString(input, Base64.NO_WRAP); 96} catch (Exception e) { 97e.printStackTrace(); 98} 99return ""; 100 }

View Code以上是标题所述语言DES加解密算法的实现,加密中并未用到IV(向量),如有需要的友人可自行添加测试。
 

    推荐阅读