多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现相关的知识,希望对你有一定的参考价值。
直入主题;前段时间根据公司对开发API的安全性要求,采用了小数据加密验证的方式,根据需求采用了三重DES加密算法。在实施的过程中发现各个语言之间加密由于加密补位的方式有所不同,导致不同语言之间加密之后无法相互解析。在强大的会联网技术和公司其他同事的支持下,最终整合了集Java,C#,Ruby,C++,Objective-C,android多语言的可以互通的TripleDES加密算法,虽然在AES加密推崇的今天DES有些乏力,但小可大胆贴上代码,希望能给大家提供一些思路。
Java DES加密(Java只提供了加密算法)
/** * 密钥算法 */ 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); }
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) { 8 var toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt); 9 var keyArray = Convert.FromBase64String(key); 10 TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider { 11 Key = keyArray, 12 Mode = CipherMode.ECB, 13 Padding = PaddingMode.PKCS7 14 }; 15 ICryptoTransform cTransform = tdes.CreateEncryptor(); 16 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 17 tdes.Clear(); 18 return 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) { 27 try { 28 //先base64解密 因为加密的时候最后走了一道base64加密 29 var enBytes = Convert.FromBase64String(toDecrypt); 30 var keyArray = Convert.FromBase64String(key); 31 TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider { 32 Key = keyArray, 33 Mode = CipherMode.ECB, 34 Padding = PaddingMode.PKCS7 35 }; 36 37 ICryptoTransform cTransform = tdes.CreateDecryptor(); 38 byte[] resultArray = cTransform.TransformFinalBlock(enBytes, 0, enBytes.Length); 39 tdes.Clear(); 40 41 return Encoding.UTF8.GetString(resultArray); 42 } catch { 43 return ""; 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 = Base64.encode64(encrypted) data.gsub!("\n", ‘‘) end def 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加解密实现
1 int base64_decode(const unsigned char *in_str, int in_len, unsigned char *out_str) 2 { 3 BIO *b64, *bio; 4 /*BUF_MEM *bptr = NULL;*/ 5 /*int counts;*/ 6 int size = 0; 7 8 if (in_str == NULL || out_str == NULL) 9 return -1; 10 11 b64 = BIO_new(BIO_f_base64()); 12 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 13 14 bio = BIO_new_mem_buf(in_str, in_len); 15 bio = BIO_push(b64, bio); 16 17 size = BIO_read(bio, out_str, in_len); 18 out_str[size] = ‘\0‘; 19 20 BIO_free_all(bio); 21 return size; 22 } 23 24 25 // OpenSSL Base64编码 26 size_t Base64Encode(const unsigned char *strCipher, size_t length, bool newLine, unsigned char* strBase64Cipher) 27 { 28 size_t len = 0; 29 BIO *bmem = NULL; 30 BIO *b64 = NULL; 31 BUF_MEM *bptr; 32 33 b64 = BIO_new(BIO_f_base64()); 34 if (!newLine) { 35 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 36 } 37 bmem = BIO_new(BIO_s_mem()); 38 b64 = BIO_push(b64, bmem); 39 BIO_write(b64, strCipher, length); 40 BIO_flush(b64); 41 BIO_get_mem_ptr(b64, &bptr); 42 BIO_set_close(b64, BIO_NOCLOSE); 43 44 unsigned char *encBuff = (unsigned char *)malloc(bptr->length + 1); 45 memcpy(encBuff, bptr->data, bptr->length); 46 encBuff[bptr->length] = 0; 47 BIO_free_all(b64); 48 49 len = strlen((const char*)encBuff); 50 for (size_t i = 0; i < len; i++) 51 { 52 *(strBase64Cipher + i) = encBuff[i]; 53 } 54 55 free(encBuff); 56 return 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;*/ 63 BIO *b64 = NULL; 64 BIO *bmem = NULL; 65 unsigned char *decBuffer = (unsigned char *)malloc(length); 66 memset(decBuffer, 0, length); 67 b64 = BIO_new(BIO_f_base64()); 68 if (!newLine) { 69 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 70 } 71 bmem = BIO_new_mem_buf(strHex, length); 72 bmem = BIO_push(b64, bmem); 73 BIO_read(bmem, decBuffer, length); 74 BIO_free_all(bmem); 75 76 /*len = strlen((const char*)decBuffer); 77 for (size_t i = 0; i < len; i++) 78 { 79 *(strDec + i) = decBuffer[i]; 80 } 81 82 free(decBuffer);*/ 83 return 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 { 90 unsigned char* decKey = NULL; 91 unsigned char* decIV = NULL; 92 unsigned char strCipher[500] = {0}; 93 94 decKey = Base64Decode(strHexKey, 32, 0); 95 if (strHexIV) 96 { 97 decIV = Base64Decode(strHexIV, 32, 0); 98 } 99 100 size_t cLen = 0; 101 size_t temp = 0; 102 //初始化密码算法结构体 103 EVP_CIPHER_CTX ctx; 104 EVP_CIPHER_CTX_init(&ctx); 105 // 加密初始化,设置加密模式为:3DES-ECB,并将密钥转换为内部密钥形式 106 EVP_EncryptInit_ex(&ctx, 107 EVP_des_ede3_ecb(), 108 NULL, 109 decKey, 110 decIV); 111 free(decKey); 112 free(decIV); 113 114 // 对strPlain进行加密 115 if (!EVP_EncryptUpdate(&ctx, strCipher, &cLen, strPlain, pLen)) 116 { 117 EVP_CIPHER_CTX_cleanup(&ctx); 118 return 0; 119 } 120 // 加密ctx的buffer中余下的数据 121 if (!EVP_EncryptFinal_ex(&ctx, strCipher + cLen, &temp)) 122 { 123 EVP_CIPHER_CTX_cleanup(&ctx); 124 return 0; 125 } 126 127 cLen += temp; 128 EVP_CIPHER_CTX_cleanup(&ctx); 129 Base64Encode(strCipher, cLen, 0, strBase64Cipher); 130 return 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 { 137 int size = 0; 138 unsigned char* decKey = NULL; 139 unsigned char* decIV = NULL; 140 /*unsigned char* decCipher = NULL;*/ 141 unsigned char decCipher[500] = { 0 }; 142 143 decKey = Base64Decode(strHexKey, 32, 0); 144 if (strHexIV) 145 { 146 decIV = Base64Decode(strHexIV, 32, 0); 147 } 148 149 /*decCipher = Base64Decode(strCipher, cLen, 0);*/ 150 151 size = base64_decode(strCipher, cLen, decCipher); 152 153 size_t temp = 0; 154 //初始化密码算法结构体 155 EVP_CIPHER_CTX ctx; 156 EVP_CIPHER_CTX_init(&ctx); 157 // 解密初始化,设置解密模式为:3DES-ECB,并将密钥转换为内部密钥形式 158 EVP_DecryptInit_ex(&ctx, EVP_des_ede3_ecb(), NULL, decKey, decIV); 159 // 对cipher进行解密 160 if (!EVP_DecryptUpdate(&ctx, strPlain, &pLen, decCipher, size)) 161 { 162 EVP_CIPHER_CTX_cleanup(&ctx); 163 return 0; 164 } 165 166 // 解密ctx的buffer中余下的数据 167 if (!EVP_DecryptFinal_ex(&ctx, strPlain + pLen, &temp)) 168 { 169 EVP_CIPHER_CTX_cleanup(&ctx); 170 return 0; 171 } 172 173 pLen += temp; 174 strPlain[pLen] = ‘\0‘; 175 EVP_CIPHER_CTX_cleanup(&ctx); 176 177 free(decKey); 178 free(decIV); 179 /*free(decCipher);*/ 180 return pLen; 181 }
Obj-c 加密实现
1 //Des加密 2 NSString *yw_encryptUseDES(NSString *plainText, NSString *key){ 3 NSData *keyData = [GTMBase64 decodeString:key]; 4 NSString *ciphertext = nil; 5 NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; 6 NSUInteger dataLength = [textData length]; 7 NSMutableData* outputData = [NSMutableData dataWithLength:(textData.length + kCCBlockSize3DES)]; 8 size_t outLength; 9 CCCryptorStatus result = CCCrypt(kCCEncrypt, // CCOperation op 10 kCCAlgorithm3DES, // CCAlgorithm alg 11 kCCOptionPKCS7Padding | kCCOptionECBMode, // CCOptions options 12 keyData.bytes, // const void *key 13 keyData.length, // size_t keyLength 14 nil, // const void *iv 15 textData.bytes, // const void *dataIn 16 dataLength, // size_t dataInLength 17 outputData.mutableBytes, // void *dataOut 18 outputData.length, // size_t dataOutAvailable 19 &outLength); 20 21 if (result != kCCSuccess) 22 return nil; 23 24 [outputData setLength:outLength]; 25 ciphertext = [GTMBase64 stringByEncodingData:outputData]; 26 return ciphertext; 27 }
Android实现代码:Android和Java差不多,上面Java代码缺少解密实现,加密的可以参考此处
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密钥 18 SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM); 19 return 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 //还原密钥 31 Key k = toKey(key); 32 //实例化 33 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 34 //初始化 35 cipher.init(Cipher.ENCRYPT_MODE, k); 36 //执行操作 37 return 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 //还原密钥 49 Key k = toKey(key); 50 //实例化 51 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); 52 //初始化 53 cipher.init(Cipher.DECRYPT_MODE, k); 54 //执行操作 55 return cipher.doFinal(data); 56 } 57 58 /** 59 * 初始化密钥 60 * @return 61 * @throws Exception 62 */ 63 public static byte[] initKey() throws Exception{ 64 //实例化KeyGenerator 65 KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM); 66 //初始化 67 keyGenerator.init(168); 68 //生成密钥 69 SecretKey secretKey = keyGenerator.generateKey(); 70 //返回密钥 71 return 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 90 byte[] keyByte = Base64.decode(secretKey, Base64.NO_WRAP); 91 byte[] plain = null; 92 try { 93 plain = plainText.getBytes("UTF-8"); 94 byte[] input = DESedeUtil.encrypt(plain, keyByte); 95 return Base64.encodeToString(input, Base64.NO_WRAP); 96 } catch (Exception e) { 97 e.printStackTrace(); 98 } 99 return ""; 100 }
以上是标题所述语言DES加解密算法的实现,加密中并未用到IV(向量),如有需要的友人可自行添加测试。
以上是关于多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现的主要内容,如果未能解决你的问题,请参考以下文章
Vs Code使用国际化多语言插件-i18n Ally&Vue i18n-插件使用