//AES 高级加密标准 Advanced Encryption Standard 的缩写public class JiamiActivity extends AppCompatActivity { private Button jiaMi; private Button jieMi; private EditText editText; public static SecretKeySpec AESKeySpec;//大小 private Button jiaMi2; private byte[] bytes2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_jiami); initView(); } private void initView() { jiaMi = (Button) findViewById(R.id.jiamiId); jiaMi2 = (Button) findViewById(R.id.jiamiId2); jieMi = (Button) findViewById(R.id.jiemiId); editText = (EditText) findViewById(R.id.etTextId); jiaMi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { testGenerateAESKey(128); } catch (Exception e) { e.printStackTrace(); } } }); jiaMi2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { testGenerateAESKey(256); } catch (Exception e) { e.printStackTrace(); } } }); } //测试生成的Key public void testGenerateAESKey(int keySize) throws Exception { String str=editText.getText().toString(); if ((keySize != 128) && (keySize != 256)) { keySize = 256; } System.out.println("测试AES " + keySize + " 生成Key加密解密"); AESKeySpec = getAESKeySpec(keySize); if (keySize == 128) { System.out.println("获得加密的Key的字符串="+getAESKeyString()); } else { System.out.println(getAES256KeyString()); } System.out.println("用户输入的原始明文="+str); String cipherText = jiaMi(str); System.out.println("加密后的密文="+cipherText); String plainText = jieMi(cipherText); System.out.println("解密后的明文="+plainText); } // 加密 public String jiaMi(String text) throws Exception { Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, AESKeySpec); //BASE64Encoder enc = new BASE64Encoder(); byte[] byteEnc = cipher.doFinal(text.getBytes("UTF-8")); //return enc.encode(byteEnc); return JiamiAndJiemiUtil.byte2hex(byteEnc); } //解密 public String jieMi(String text) throws Exception { Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, AESKeySpec); //BASE64Decoder dec = new BASE64Decoder(); //return new String(cipher.doFinal(dec.decodeBuffer(text))); return new String(cipher.doFinal(JiamiAndJiemiUtil.hex2byte(text.getBytes("UTF-8")))); } // 取得AES的Key(秘钥) public SecretKeySpec getAESKeySpec(int keySize) throws IOException, NoSuchAlgorithmException { SecretKey key = null; SecretKeySpec spec = null; if ((keySize != 128) && (keySize != 192) && (keySize != 256)) { keySize = 256; } if(keySize==256){ bytes2 = new byte[keySize/8]; String fileName="256case.txt"; File f = new File(this.getFilesDir(),fileName); Log.i("TAG","f的路径="+f.getPath()); Log.i("TAG","f="+f.getName()); // 如果存在Key文件,读取 if (f.exists()) { new FileInputStream(f).read(bytes2); } // 如果不存在,重新生成Key,并写入Key文件 else { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(keySize); key = kgen.generateKey(); System.out.println("++++++++++++++++++++:key="+key); bytes2 = key.getEncoded(); System.out.println("bytes="+bytes2); new FileOutputStream(f).write(bytes2); } spec = new SecretKeySpec(bytes2, "AES"); return spec; }else{ // AES 128 位 byte[] bytes = new byte[keySize / 8]; String fileName="128case.txt"; File f = new File(this.getFilesDir(),fileName); Log.i("TAG","f的路径="+f.getPath()); Log.i("TAG","f="+f.getName()); // 如果存在Key文件,读取 if (f.exists()) { new FileInputStream(f).read(bytes); } // 如果不存在,重新生成Key,并写入Key文件 else { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(keySize); key = kgen.generateKey(); System.out.println("++++++++++++++++++++:key="+key); bytes = key.getEncoded(); System.out.println("bytes="+bytes); new FileOutputStream(f).write(bytes); } spec = new SecretKeySpec(bytes, "AES"); return spec; } } // 取得AES Key对应的字符串,傳遞此key 到Objective C public static String getAESKeyString() { // return new String(AESKeySpec.getEncoded()); return JiamiAndJiemiUtil.byte2hex(AESKeySpec.getEncoded()); } // 取得AES Key对应的字符串,传递此key 到Objective C public static String getAES256KeyString() { // return new BASE64Encoder().encode(AESKeySpec.getEncoded()); return JiamiAndJiemiUtil.byte2hex(AESKeySpec.getEncoded()); } }点击128加密和点击256加密后的结果如下:
I/System.out: 测试AES 128 生成Key加密解密 I/TAG: f的路径=/data/user/0/james.myview/files/128case.txt I/TAG: f=128case.txt I/System.out: 获得128加密的Key的字符串=EE66D58C8FFC188648B8C32720FAB304 I/System.out: 用户输入的原始明文=lulu I/System.out: 加密后的密文=8D13E32DB1BEC38C8EE7D414F2F380E0 I/System.out: 解密后的明文=lulu I/System.out: 测试AES 256 生成Key加密解密 I/TAG: f的路径=/data/user/0/james.myview/files/256case.txt I/TAG: f=256case.txt I/System.out: 获得256加密的Key的字符串=12109BCA993D53D3E2C3F2874469035604755EEEDB936C4F104AE4FBB049CADA I/System.out: 用户输入的原始明文=lulu I/System.out: 加密后的密文=8F7C7B040D53068F6720DF68FB12670A I/System.out: 解密后的明文=lulu
public class JiamiAndJiemiUtil { //字节到十六进制的转换 public static String byte2hex(byte[] b){ String hs = ""; String stmp = ""; for (int n = 0; n < b.length; n ++){ stmp = Integer.toHexString(b[n] & 0xFF); if (stmp.length() == 1) hs += ("0" + stmp); else hs += stmp; } return hs.toUpperCase(); } //十六进制到字节转换 public static byte[] hex2byte(byte[] b){ if ((b.length % 2) != 0) throw new IllegalArgumentException("长度不是偶数!"); byte[] b2 = new byte[b.length / 2]; for (int n = 0; n < b.length; n += 2){ String item = new String(b, n, 2); b2[n/2] = (byte)Integer.parseInt(item, 16); } return b2; } }
另外一个网友的加密实现
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AESPlus {
//获得一个私鈅加密类Cipher,ECB是加密方式,PKCS5Padding是填充方法
}