多语言(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);
}
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) {
 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 }
View Code

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 }
View Code

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

 

以上是关于多语言(Java&C#&Ruby&C++&Objective-C&Android)互通的TripleDES加解密算法实现的主要内容,如果未能解决你的问题,请参考以下文章

下一代的多语言JVM:GraalVM

ruby Rails中的双向多语言关联

Vs Code使用国际化多语言插件-i18n Ally&Vue i18n-插件使用

多语言php脚本

PaddleOCR 部署实战之Java&C#方案直播分享来啦

PaddleOCR 部署实战之Java&C#方案直播分享来啦