java 如何在Android上使用3DES算法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16336017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:40:29  来源:igfitidea点击:

How to use 3DES algorithm on Android?

javaandroid3des

提问by user2326860

On the server side, the encyption/decryption of the password field is done in C#.

在服务器端,密码字段的加密/解密是在 C# 中完成的。

Now, i need to implement same functionality in my android application. So, i followed this tutorial: http://ttux.net/post/3des-java-encrypter-des-java-encryption/as below:

现在,我需要在我的 android 应用程序中实现相同的功能。所以,我跟着这个教程:http: //ttux.net/post/3des-java-encrypter-des-java-encryption/如下:

    import java.security.MessageDigest; 
import java.security.spec.KeySpec; 
import java.util.Arrays; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESedeKeySpec; 
import javax.crypto.spec.IvParameterSpec; 

import org.apache.commons.codec.binary.Base64; 

public class Encrypter { 
  private KeySpec keySpec; 
  private SecretKey key; 
  private IvParameterSpec iv; 

  public Encrypter(String keyString, String ivString) { 
    try { 
      final MessageDigest md = MessageDigest.getInstance("md5"); 
      final byte[] digestOfPassword = md.digest(Base64.decodeBase64(keyString.getBytes("utf-8"))); 
      final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); 
      for (int j = 0, k = 16; j < 8;) { 
    keyBytes[k++] = keyBytes[j++]; 
      } 

      keySpec = new DESedeKeySpec(keyBytes); 

      key = SecretKeyFactory.getInstance("DESede").generateSecret(keySpec); 

      iv = new IvParameterSpec(ivString.getBytes()); 
    } catch(Exception e) { 
      e.printStackTrace(); 
    } 
  } 

  public String encrypt(String value) { 
    try { 
      Cipher ecipher = Cipher.getInstance("DESede/CBC/PKCS5Padding","SunJCE"); 
      ecipher.init(Cipher.ENCRYPT_MODE, key, iv); 

      if(value==null) 
    return null; 

      // Encode the string into bytes using utf-8 
      byte[] utf8 = value.getBytes("UTF8"); 

      // Encrypt 
      byte[] enc = ecipher.doFinal(utf8); 

      // Encode bytes to base64 to get a string 
      return new String(Base64.encodeBase64(enc),"UTF-8"); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return null; 
  } 

  public String decrypt(String value) { 
    try { 
      Cipher dcipher = Cipher.getInstance("DESede/CBC/PKCS5Padding","SunJCE"); 
      dcipher.init(Cipher.DECRYPT_MODE, key, iv); 

      if(value==null) 
    return null; 

      // Decode base64 to get bytes 
      byte[] dec = Base64.decodeBase64(value.getBytes()); 

      // Decrypt 
      byte[] utf8 = dcipher.doFinal(dec); 

      // Decode using utf-8 
      return new String(utf8, "UTF8"); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return null; 
  } 
} 

but i dont know what values i need to provide for KeyValue and ivValue for the above code. Please help me...

但我不知道我需要为上述代码的 KeyValue 和 ivValue 提供什么值。请帮我...

回答by onkar

Use this code to encrypt your string

使用此代码加密您的字符串

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import android.util.Base64;
//string encryption
public class EncryptionHelper {



    // Encrypts string and encode in Base64
    public static String encryptText(String plainText) throws Exception {
        // ---- Use specified 3DES key and IV from other source --------------
        byte[] plaintext = plainText.getBytes();//input
        byte[] tdesKeyData = Constants.getKey().getBytes();// your encryption key

        byte[] myIV = Constants.getInitializationVector().getBytes();// initialization vector

        Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(myIV);

        c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
        byte[] cipherText = c3des.doFinal(plaintext);
        String encryptedString = Base64.encodeToString(cipherText,
                Base64.DEFAULT);
        // return Base64Coder.encodeString(new String(cipherText));
        return encryptedString;
    }

}

This is how you can encrypt the string

这是加密字符串的方法

String encryptedPassword = EncryptionHelper.encryptText(edtText.getText().toString());

EDITCode for Constants.java

编辑代码Constants.java

     Class Constants {
         private final String initializationVector = "INITALIZATION_VECTOR";
         private final String ecnryptionKey = "ENCRYPTION_KEY";
         public static String getInitializationVector() {
             return initializationVector;
         }
         public static String getKey() {
             return ecnryptionKey;
         }
     }

回答by Maarten Bodewes

Triple DES is called "DESede"(DES using single DES Encrypt, Decrypt, Encrypt for encryption) in both Java and Android runtimes. So it is build in functionality which can be access through the Cipherclass. It also lists the available algorithms. For triple DES you could use "DESede/CBC/PKCS5Padding"`. Don't forget to supply it a random IV of 8 bytes.

"DESede"Java 和 Android 运行时都称为三重 DES (DES 使用单个 DES 加密、解密、加密进行加密)。所以它是可以通过Cipher类访问的内置功能。它还列出了可用的算法。对于三重 DES,您可以使用“DESede/CBC/PKCS5Padding”`。不要忘记为它提供一个 8 字节的随机 IV。

Triple DES should only be used for backwards compatibility. If you decide to use it at least supply it 24 bytes of key material, otherwise there is a chance that your ciphertext can be cracked. For a more modern approach use AES, preferably in an authenticated mode such as GCM ("AES/GCM/NoPadding"). Note that GCM requires a unique nonce of 12 bytes.

三重 DES 应仅用于向后兼容。如果您决定使用它至少提供 24 字节的密钥材料,否则您的密文就有可能被破解。对于更现代的方法,请使用 AES,最好采用经过身份验证的模式,例如 GCM ( "AES/GCM/NoPadding")。请注意,GCM 需要 12 个字节的唯一随机数。