AES加密算法模式有四种:ECB、CBC、CFB、OFB

要想AES加密,至少需要一个16位的密钥,如果是非ECB模式的加密,至少还得需要密钥偏移量。

下面是AES在线加密解密链接:

AES在线加密解密链接

如上图所示:“hello everyone!”被加密成了“X/T+Vxr5QZEp/GBr/iul8w==”

好的,那如何用android代码实现这样的加密呢?网上代码不少,但是有的确是很混乱,我现在来整理整理

主要代码如下:

AES.java类:

public class AES {private final String KEY_GENERATION_ALG = "PBEWITHSHAANDTWOFISH-CBC";// private final String KEY_GENERATION_ALG = "PBKDF2WithHmacSHA1";private final int HASH_ITERATIONS = 10000;private final int KEY_LENGTH = 128;private char[] humanPassphrase = { 'P', 'e', 'r', ' ', 'v', 'a', 'l', 'l','u', 'm', ' ', 'd', 'u', 'c', 'e', 's', ' ', 'L', 'a', 'b', 'a','n', 't' };// per vallum duces labantprivate byte[] salt = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD,0xE, 0xF }; // must save this for next time we want the keyprivate PBEKeySpec myKeyspec = new PBEKeySpec(humanPassphrase, salt,HASH_ITERATIONS, KEY_LENGTH);private final String CIPHERMODEPADDING = "AES/CBC/PKCS5Padding";// AES/CBC/PKCS7Paddingprivate SecretKeyFactory keyfactory = null;private SecretKey sk = null;private SecretKeySpec skforAES = null;private static String ivParameter = "1234567890123456";// 密钥默认偏移,可更改// private byte[] iv = { 0xA, 1, 0xB, 5, 4, 0xF, 7, 9, 0x17, 3, 1, 6, 8,// 0xC,// 0xD, 91 };private byte[] iv = ivParameter.getBytes();private IvParameterSpec IV;String sKey = "1234567890123456";// key必须为16位,可更改为自己的keypublic AES() {try {keyfactory = SecretKeyFactory.getInstance(KEY_GENERATION_ALG);sk = keyfactory.generateSecret(myKeyspec);} catch (NoSuchAlgorithmException nsae) {Log.e("AESdemo","no key factory support for PBEWITHSHAANDTWOFISH-CBC");} catch (InvalidKeySpecException ikse) {Log.e("AESdemo", "invalid key spec for PBEWITHSHAANDTWOFISH-CBC");}// This is our secret key. We could just save this to a file instead of// regenerating it// each time it is needed. But that file cannot be on the device (too// insecure). It could// be secure if we kept it on a server accessible through https.// byte[] skAsByteArray = sk.getEncoded();byte[] skAsByteArray;try {skAsByteArray = sKey.getBytes("ASCII");skforAES = new SecretKeySpec(skAsByteArray, "AES");} catch (UnsupportedEncodingException e) {e.printStackTrace();}IV = new IvParameterSpec(iv);}public String encrypt(byte[] plaintext) {byte[] ciphertext = encrypt(CIPHERMODEPADDING, skforAES, IV, plaintext);String base64_ciphertext = Base64Encoder.encode(ciphertext);return base64_ciphertext;}public String decrypt(String ciphertext_base64) {byte[] s = Base64Decoder.decodeToBytes(ciphertext_base64);String decrypted = new String(decrypt(CIPHERMODEPADDING, skforAES, IV,s));return decrypted;}// Use this method if you want to add the padding manually// AES deals with messages in blocks of 16 bytes.// This method looks at the length of the message, and adds bytes at the end// so that the entire message is a multiple of 16 bytes.// the padding is a series of bytes, each set to the total bytes added (a// number in range 1..16).private byte[] addPadding(byte[] plain) {byte plainpad[] = null;int shortage = 16 - (plain.length % 16);// if already an exact multiple of 16, need to add another block of 16// bytesif (shortage == 0)shortage = 16;// reallocate array bigger to be exact multiple, adding shortage bits.plainpad = new byte[plain.length + shortage];for (int i = 0; i < plain.length; i++) {plainpad[i] = plain[i];}for (int i = plain.length; i < plain.length + shortage; i++) {plainpad[i] = (byte) shortage;}return plainpad;}// Use this method if you want to remove the padding manually// This method removes the padding bytesprivate byte[] dropPadding(byte[] plainpad) {byte plain[] = null;int drop = plainpad[plainpad.length - 1]; // last byte gives number of// bytes to drop// reallocate array smaller, dropping the pad bytes.plain = new byte[plainpad.length - drop];for (int i = 0; i < plain.length; i++) {plain[i] = plainpad[i];plainpad[i] = 0; // don't keep a copy of the decrypt}return plain;}private byte[] encrypt(String cmp, SecretKey sk, IvParameterSpec IV,byte[] msg) {try {Cipher c = Cipher.getInstance(cmp);c.init(Cipher.ENCRYPT_MODE, sk, IV);return c.doFinal(msg);} catch (NoSuchAlgorithmException nsae) {Log.e("AESdemo", "no cipher getinstance support for " + cmp);} catch (NoSuchPaddingException nspe) {Log.e("AESdemo", "no cipher getinstance support for padding " + cmp);} catch (InvalidKeyException e) {Log.e("AESdemo", "invalid key exception");} catch (InvalidAlgorithmParameterException e) {Log.e("AESdemo", "invalid algorithm parameter exception");} catch (IllegalBlockSizeException e) {Log.e("AESdemo", "illegal block size exception");} catch (BadPaddingException e) {Log.e("AESdemo", "bad padding exception");}return null;}private byte[] decrypt(String cmp, SecretKey sk, IvParameterSpec IV,byte[] ciphertext) {try {Cipher c = Cipher.getInstance(cmp);c.init(Cipher.DECRYPT_MODE, sk, IV);return c.doFinal(ciphertext);} catch (NoSuchAlgorithmException nsae) {Log.e("AESdemo", "no cipher getinstance support for " + cmp);} catch (NoSuchPaddingException nspe) {Log.e("AESdemo", "no cipher getinstance support for padding " + cmp);} catch (InvalidKeyException e) {Log.e("AESdemo", "invalid key exception");} catch (InvalidAlgorithmParameterException e) {Log.e("AESdemo", "invalid algorithm parameter exception");} catch (IllegalBlockSizeException e) {Log.e("AESdemo", "illegal block size exception");} catch (BadPaddingException e) {Log.e("AESdemo", "bad padding exception");e.printStackTrace();}return null;}
}

Base64Decoder.java类:

package com.test.aesforandroid;import java.io.*;public class Base64Decoder extends FilterInputStream {private static final char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G','H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T','U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g','h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6','7', '8', '9', '+', '/' };// A mapping between char values and six-bit integersprivate static final int[] ints = new int[128];static {for (int i = 0; i < 64; i++) {ints[chars[i]] = i;}}private int charCount;private int carryOver;/**** Constructs a new Base64 decoder that reads input from the given* InputStream.* * @param in*            the input stream*/public Base64Decoder(InputStream in) {super(in);}/**** Returns the next decoded character from the stream, or -1 if end of* stream was reached.* * @return the decoded character, or -1 if the end of the input stream is*         reached* @exception IOException*                if an I/O error occurs*/public int read() throws IOException {// Read the next non-whitespace characterint x;do {x = in.read();if (x == -1) {return -1;}} while (Character.isWhitespace((char) x));charCount++;// The '=' sign is just paddingif (x == '=') {return -1; // effective end of stream}// Convert from raw form to 6-bit formx = ints[x];// Calculate which character we're decoding nowint mode = (charCount - 1) % 4;// First char save all six bits, go for anotherif (mode == 0) {carryOver = x & 63;return read();}// Second char use previous six bits and first two new bits,// save last four bitselse if (mode == 1) {int decoded = ((carryOver << 2) + (x >> 4)) & 255;carryOver = x & 15;return decoded;}// Third char use previous four bits and first four new bits,// save last two bitselse if (mode == 2) {int decoded = ((carryOver << 4) + (x >> 2)) & 255;carryOver = x & 3;return decoded;}// Fourth char use previous two bits and all six new bitselse if (mode == 3) {int decoded = ((carryOver << 6) + x) & 255;return decoded;}return -1; // can't actually reach this line}/**** Reads decoded data into an array of bytes and returns the actual number* of bytes read, or -1 if end of stream was reached.* * @param buf*            the buffer into which the data is read* @param off*            the start offset of the data* @param len*            the maximum number of bytes to read* @return the actual number of bytes read, or -1 if the end of the input*         stream is reached* @exception IOException*                if an I/O error occurs*/public int read(byte[] buf, int off, int len) throws IOException {if (buf.length < (len + off - 1)) {throw new IOException("The input buffer is too small: " + len+ " bytes requested starting at offset " + off+ " while the buffer " + " is only " + buf.length+ " bytes long.");}// This could of course be optimizedint i;for (i = 0; i < len; i++) {int x = read();if (x == -1 && i == 0) { // an immediate -1 returns -1return -1;} else if (x == -1) { // a later -1 returns the chars read so farbreak;}buf[off + i] = (byte) x;}return i;}/**** Returns the decoded form of the given encoded string, as a String. Note* that not all binary data can be represented as a String, so this method* should only be used for encoded String data. Use decodeToBytes()* otherwise.* * @param encoded*            the string to decode* @return the decoded form of the encoded string*/public static String decode(String encoded) {return new String(decodeToBytes(encoded));}/**** Returns the decoded form of the given encoded string, as bytes.* * @param encoded*            the string to decode* @return the decoded form of the encoded string*/public static byte[] decodeToBytes(String encoded) {byte[] bytes = null;try {bytes = encoded.getBytes("UTF-8");} catch (UnsupportedEncodingException ignored) {}Base64Decoder in = new Base64Decoder(new ByteArrayInputStream(bytes));ByteArrayOutputStream out = new ByteArrayOutputStream((int) (bytes.length * 0.67));try {byte[] buf = new byte[4 * 1024]; // 4K bufferint bytesRead;while ((bytesRead = in.read(buf)) != -1) {out.write(buf, 0, bytesRead);}out.close();return out.toByteArray();} catch (IOException ignored) {return null;}}public static void main(String[] args) throws Exception {if (args.length != 1) {System.err.println("Usage: java Base64Decoder fileToDecode");return;}Base64Decoder decoder = null;try {decoder = new Base64Decoder(new BufferedInputStream(new FileInputStream(args[0])));byte[] buf = new byte[4 * 1024]; // 4K bufferint bytesRead;while ((bytesRead = decoder.read(buf)) != -1) {System.out.write(buf, 0, bytesRead);}} finally {if (decoder != null)decoder.close();}}
}

Base64Encoder.java类:

package com.test.aesforandroid;import java.io.*;public class Base64Encoder extends FilterOutputStream {private static final char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G','H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T','U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g','h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't','u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6','7', '8', '9', '+', '/' };private int charCount;private int carryOver;/**** Constructs a new Base64 encoder that writes output to the given* OutputStream.* * @param out*            the output stream*/public Base64Encoder(OutputStream out) {super(out);}/**** Writes the given byte to the output stream in an encoded form.* * @exception IOException*                if an I/O error occurs*/public void write(int b) throws IOException {// Take 24-bits from three octets, translate into four encoded chars// Break lines at 76 chars// If necessary, pad with 0 bits on the right at the end// Use = signs as padding at the end to ensure encodedLength % 4 == 0// Remove the sign bit,// thanks to Christian Schweingruber <chrigu@lorraine.ch>if (b < 0) {b += 256;}// First byte use first six bits, save last two bitsif (charCount % 3 == 0) {int lookup = b >> 2;carryOver = b & 3; // last two bitsout.write(chars[lookup]);}// Second byte use previous two bits and first four new bits,// save last four bitselse if (charCount % 3 == 1) {int lookup = ((carryOver << 4) + (b >> 4)) & 63;carryOver = b & 15; // last four bitsout.write(chars[lookup]);}// Third byte use previous four bits and first two new bits,// then use last six new bitselse if (charCount % 3 == 2) {int lookup = ((carryOver << 2) + (b >> 6)) & 63;out.write(chars[lookup]);lookup = b & 63; // last six bitsout.write(chars[lookup]);carryOver = 0;}charCount++;// Add newline every 76 output chars (that's 57 input chars)if (charCount % 57 == 0) {out.write('\n');}}/**** Writes the given byte array to the output stream in an encoded form.* * @param buf*            the data to be written* @param off*            the start offset of the data* @param len*            the length of the data* @exception IOException*                if an I/O error occurs*/public void write(byte[] buf, int off, int len) throws IOException {// This could of course be optimizedfor (int i = 0; i < len; i++) {write(buf[off + i]);}}/**** Closes the stream, this MUST be called to ensure proper padding is* written to the end of the output stream.* * @exception IOException*                if an I/O error occurs*/public void close() throws IOException {// Handle leftover bytesif (charCount % 3 == 1) { // one leftoverint lookup = (carryOver << 4) & 63;out.write(chars[lookup]);out.write('=');out.write('=');} else if (charCount % 3 == 2) { // two leftoversint lookup = (carryOver << 2) & 63;out.write(chars[lookup]);out.write('=');}super.close();}/**** Returns the encoded form of the given unencoded string. The encoder uses* the ISO-8859-1 (Latin-1) encoding to convert the string to bytes. For* greater control over the encoding, encode the string to bytes yourself* and use encode(byte[]).* * @param unencoded*            the string to encode* @return the encoded form of the unencoded string*/public static String encode(String unencoded) {byte[] bytes = null;try {bytes = unencoded.getBytes("UTF-8");} catch (UnsupportedEncodingException ignored) {}return encode(bytes);}/**** Returns the encoded form of the given unencoded string.* * @param bytes*            the bytes to encode* @return the encoded form of the unencoded string*/public static String encode(byte[] bytes) {ByteArrayOutputStream out = new ByteArrayOutputStream((int) (bytes.length * 1.37));Base64Encoder encodedOut = new Base64Encoder(out);try {encodedOut.write(bytes);encodedOut.close();return out.toString("UTF-8");} catch (IOException ignored) {return null;}}public static void main(String[] args) throws Exception {if (args.length != 1) {System.err.println("Usage: java com.oreilly.servlet.Base64Encoder fileToEncode");return;}Base64Encoder encoder = null;BufferedInputStream in = null;try {encoder = new Base64Encoder(System.out);in = new BufferedInputStream(new FileInputStream(args[0]));byte[] buf = new byte[4 * 1024]; // 4K bufferint bytesRead;while ((bytesRead = in.read(buf)) != -1) {encoder.write(buf, 0, bytesRead);}} finally {if (in != null)in.close();if (encoder != null)encoder.close();}}
}

Android测试代码如下:

package com.test.aesforandroid;import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;public class MainActivity extends Activity {private TextView textView1, textView2;String mString = "hello everyone!";byte[] mBytes = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView1 = (TextView) findViewById(R.id.textView1);textView2 = (TextView) findViewById(R.id.textView2);AES mAes = new AES();try {mBytes = mString.getBytes("UTF8");} catch (Exception e) {Log.i("qing", "MainActivity----catch");}String enString = mAes.encrypt(mBytes);textView1.setText("加密后:" + enString);String deString = mAes.decrypt(enString);textView2.setText("解密后:" + deString);}
}

Run APP,可以发现界面上会出现如下图所示:

与上面在线测试工具的相比对,一模一样,棒棒哒,搞定!

附上我上传到CSDN上的代码:http://download.csdn.net/detail/qq_33237207/9678602

X/T+Vxr5QZEp/GBr/iul8w==

Android AES加密解密相关推荐

  1. Android AES加密解密工具类

    一个用于Android AES加密解密的工具类,记录一下... import android.os.Build import android.security.keystore.KeyGenParam ...

  2. java android aes加密解密_AES加密解密在JAVA和ANDROID下互通

    昨天外包安卓的那个人说AES的加解密结果不一样.于是百度搜索发现还真是! 贴上AES加密核心: Cipher cipher = Cipher.getInstance("AES/CBC/PKC ...

  3. android、ios、php之间AES加密解密

    使用原因: 因为在项目中,需要在与客户端(IOS,Android)交互的时候,保存一些私有信息,不被别人看到,所以,使用了比较流行的可以反向加解密的AES. PHP 源码 <?php$aes = ...

  4. openssl与cryptoAPI交互AES加密解密

    原文: http://blog.csdn.net/zhouyuqwert/article/details/7422467 有读者指出代码贴两遍,修改下. 继上次只有CryptoAPI的加密后,这次要实 ...

  5. ios java aes_PHP7 AES加密解密函数_兼容ios/andriod/java对等加解密

    **PHP7.0 7.1 7.2 7.3 AES对等加解密类 函数文件_兼容ios/andriod/java等** 由于新项目规划要求使用PHP7.2开发环境,但在部分新系统中仍需使用AES加解密方式 ...

  6. Android RSA加密解密的 工具类的使用

    RSA 比较特殊,我们首先要生成私钥和公钥,然后在加密的时候,使用私钥加密,在解密的时候使用公钥解密. //RSA 的初始化,获得私钥和密钥public void rsaInit(){try {Key ...

  7. Android常用加密解密实现方式

    1.MD5,SHA1加密校验 MD5,SHA1等加密算法我们通常不用来做加密,因为解密成本非常大,我们一般用MD5,SHA1等用来做文件校验,唯一性校验等功能.常见的场景如防止别人恶意篡改我们的APP ...

  8. AES加密解密(ECB模式)

    高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES, ...

  9. AES加密解密(CBC模式)

    高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES, ...

最新文章

  1. 儿童吹泡泡水简单配方_儿童吹泡泡水简单配方[组图]
  2. 怎么看rx580是不是470刷的_怎么看钻石是不是奶咖钻,钻石证书上可以看出奶咖钻石吗...
  3. 阅读之spring+Dubbo
  4. LeetCode——排序
  5. 第二十九期:运维之三大监控对比
  6. CSS隐藏内容的三种方法比较
  7. Android接口回调
  8. 【颜色识别】基于matlab机器视觉颜色识别系统【含Matlab源码 588期】
  9. wordpress单独html页面,wordpress独立留言板页面
  10. Qt 字体大小的计算
  11. 计算机软考答题卡填涂格式,软考填涂答题卡(纸)须知
  12. 图表和文字等元素在电子大屏下变形的解决方案
  13. Python基础--集合创建、添加删除元素以及集合的交集、并集和差集运算
  14. 潘悟云方言计算机,山东方言精组与见晓组声母的分合研究
  15. 如何下载头歌平台在线实验闯关中的文件到本地进行查看
  16. RAVDESS语音情感分类数据集的介绍
  17. linux jboss的安装路径,LINUX下JBOSS的安装及配置
  18. 在 Apple 芯片设备上用 Android Studio?别忘了使用 Apple 芯片预览版!
  19. 星驰云算GOSTAR,携手Swarm共建Web 3.0时代
  20. 全产业链模式的竞争优势

热门文章

  1. python爬取微信群聊内容_再不学Python 你就被同龄人甩开了吗?
  2. 关于错误:[Error] expected primary-expression before ‘int‘
  3. 图片搜索 拍立淘 按图搜索以图搜索 图搜商品 同款搜索商品
  4. 安科瑞能效管理系统在地下污水处理厂中的应用
  5. C/C++ 程序员的职业生涯规划,你想从事哪方面呢?这里都有介绍
  6. linux 查看mmc分区_查看MTD,EMMC,MMC三种设备的分区
  7. python字符串的查找
  8. 国家电网计算机专业考试科目,2019国家电网考试科目:你的专业都考什么?
  9. LINUX下安装中文输入法
  10. 电气设备常用文字符号新旧对照表