在Android中加密/解密字符串的简便方法

Sum*_*mar 16 encryption android

我的问题是如何加密字符串:

String AndroidId;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.download_movie_activity);

  cancel = (Button)findViewById(R.id.img_cancle);

  linear= (LinearLayout)findViewById(R.id.progress);
  linear.setVisibility(View.GONE);

  String encrypted = "MzIyNTE2" + "OTQNzM4NTQ=";

  Log.e("Encrypt", encrypted);

  WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
  WifiInfo wInfo = wifiManager.getConnectionInfo();
  AndroidId = wInfo.getMacAddress();

  AndroidId=encrypted;
Run Code Online (Sandbox Code Playgroud)

U如何加密我存储MAC地址的AndroidId.

Pat*_*k R 33

你可以用Cipher它.

此类提供用于加密和解密的加密密码的功能.它构成了Java Cryptographic Extension(JCE)框架的核心.

加密和解密样本:

public static SecretKey generateKey() 
    throws NoSuchAlgorithmException, InvalidKeySpecException 
{ 
    return secret = new SecretKeySpec(password.getBytes(), "AES"); 
}

public static byte[] encryptMsg(String message, SecretKey secret)
    throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException 
{ 
   /* Encrypt the message. */
   Cipher cipher = null; 
   cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
   cipher.init(Cipher.ENCRYPT_MODE, secret); 
   byte[] cipherText = cipher.doFinal(message.getBytes("UTF-8")); 
   return cipherText; 
}

public static String decryptMsg(byte[] cipherText, SecretKey secret) 
    throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException 
{
    /* Decrypt the message, given derived encContentValues and initialization vector. */
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secret); 
    String decryptString = new String(cipher.doFinal(cipherText), "UTF-8");
    return decryptString; 
}
Run Code Online (Sandbox Code Playgroud)

要加密:

SecretKey secret = generateKey();
EncUtil.encryptMsg(String toEncrypt, secret))
Run Code Online (Sandbox Code Playgroud)

要解密:

EncUtil.decryptMsg(byte[] toDecrypt, secret))
Run Code Online (Sandbox Code Playgroud)

  • "在Android N中,我们完全弃用SHA1PRNG算法和加密提供程序的实现"请点击链接获取更多信息; https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated -in.html (6认同)
  • 我经历了您的代码在解密时获取此异常。javax.crypto.IllegalBlockSizeException:解密中的最后一个块不完整 (2认同)
  • 此代码有许多严重的问题,不应使用。例如,直接从 password.getBytes 生成密钥并使用 ECB 模式。 (2认同)
  • @ IsaacPotoczny-Jones,你能告诉其他apporaches的一些细节吗? (2认同)

var*_*jsi 17

使用这些帮助程序类,您可以在Android中简单地加密和解密字符串,但这只适用于Android 7.0以下,对于Android 8.0及更高版本,您可以从这里找到

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESHelper {

public static String encrypt(String seed, String cleartext) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes());
    return toHex(result);
}

public static String decrypt(String seed, String encrypted) throws Exception {
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] enc = toByte(encrypted);
    byte[] result = decrypt(rawKey, enc);
    return new String(result);
}

private static byte[] getRawKey(byte[] seed) throws Exception {
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG","Crypto");
    sr.setSeed(seed);
    kgen.init(128, sr); // 192 and 256 bits may not be available
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    return raw;
}


private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] decrypted = cipher.doFinal(encrypted);
    return decrypted;
}

public static String toHex(String txt) {
    return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
    return new String(toByte(hex));
}

public static byte[] toByte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
Run Code Online (Sandbox Code Playgroud)

下面是你的字符串加密和解密方法,

public String encryption(String strNormalText){
    String seedValue = "YourSecKey";
    String normalTextEnc="";
    try {
        normalTextEnc = AESHelper.encrypt(seedValue, strNormalText);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return normalTextEnc;
}
public String decryption(String strEncryptedText){
    String seedValue = "YourSecKey";
    String strDecryptedText="";
    try {
        strDecryptedText = AESHelper.decrypt(seedValue, strEncryptedText);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return strDecryptedText;
}
Run Code Online (Sandbox Code Playgroud)

最后你可以使用像:

String encryptedString = encryption("Input Normal String");
String decryptedString = decryption("Input Encrypted String");
Run Code Online (Sandbox Code Playgroud)

  • 为什么重新发明轮子?使用[library](https://github.com/ryan652/EasyCrypt)来避免实施漏洞. (4认同)
  • java.security.NoSuchProviderException:没有这样的提供者:加密 (3认同)

Ruz*_*zin 9

事实上,Saravanan Ee 的 答案是正确的。但存在一些逻辑和语法错误。这是他的方法的正确代码片段。

private String SECRET_KEY = "aesEncryptionKey";
private String INIT_VECTOR = "encryptionIntVec";

public static String encrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
     
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
     
        byte[] encrypted = cipher.doFinal(value.getBytes());
        return Base64.encodeToString(encrypted, Base64.DEFAULT);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

public static String decrypt(String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), "AES");
     
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] original = cipher.doFinal(Base64.decode(value, Base64.DEFAULT));
     
        return new String(original);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
     
    return null;
}
Run Code Online (Sandbox Code Playgroud)

用法:

加密:

String textForEncryption = "This my text that will be encrypted!";
String encryptedString;
encryptedString = encrypt(textForEncryption);
//Result: BItjtWPNKXjdHZ6clbtXWAzUwJAbMpIaP294eRB9+7BR0g+gJ9jZv4AZt+8epG36
Run Code Online (Sandbox Code Playgroud)

解密:

String encryptedText = "BItjtWPNKXjdHZ6clbtXWAzUwJAbMpIaP294eRB9+7BR0g+gJ9jZv4AZt+8epG36";
String decryptedString;
decryptedString = decrypt(encryptedText);
//Result: This my text that will be encrypted!
Run Code Online (Sandbox Code Playgroud)


Dun*_*una 7

请阅读

新版Android SDK不再支持该Crypto提供商.

如果您的应用程序依赖于setSeed()从字符串派生密钥,您应该切换到使用SecretKeySpec直接加载原始密钥字节 使用实际密钥派生函数(KDF).

在这里查看建议:

http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html

  • 使用此库代替使用android 7. + https://github.com/scottyab/AESCrypt-Android (6认同)