1.自己写一个类RSAUtils把下面的代码添加进去
static class RSAUtils{
//这里的参数随便写
private static final String PRIVATE_KEY ="1" ;
private static final String PUBLIC_KEY ="2" ;
/**
* 计算出公钥私钥用map存储
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* <p>
* 获取私钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static Key getPrivateKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key;
// return Base64Utils.encode(key.getEncoded());
}
/**
* <p>
* 获取公钥
* </p>
*
* @param keyMap 密钥对
* @return
* @throws Exception
*/
public static Key getPublicKey(Map<String, Object> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key;
//return Base64Utils.encode(key.getEncoded());
}
/**
* 加密
*
* @param key 加密的密钥
* @param data 待加密的明文数据
* @return 加密后的数据
* @throws Exception
*/
public byte[] encrypt(Key key, byte[] data) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;
//因此共有2个加密块,第一个127 byte第二个为1个byte
int blockSize = cipher.getBlockSize();
int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小
int leavedSize = data.length % blockSize;
int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
byte[] raw = new byte[outputSize * blocksSize];
int i = 0;
while (data.length - i * blockSize > 0) {
if (data.length - i * blockSize > blockSize)
cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
else
cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
//这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中
//,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。
i++;
}
return raw;
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
/**
* 解密
*
* @param key 解密的密钥
* @param raw 已经加密的数据
* @return 解密后的明文
* @throws Exception
*/
public byte[] decrypt(Key key, byte[] raw) throws Exception {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(cipher.DECRYPT_MODE, key);
int blockSize = cipher.getBlockSize();
ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
int j = 0;
while (raw.length - j * blockSize > 0) {
bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
j++;
}
return bout.toByteArray();
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
}
}
2.自己在创建个类Base64Helper把下面的添加进去
import android.util.Base64;
public class Base64Helper {
//base64编码原文是否是6的整数倍?末尾几个“=”号?
public static String encode(byte[] data) {
return Base64.encodeToString(data, Base64.DEFAULT);
}
public static byte[] decode(String str) {
return Base64.decode(str, Base64.DEFAULT);
}
}
3.主布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="comqq.example.hasee.myapplication.MainActivity"
android:orientation="vertical">
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Hello World!" />
<Button
android:id="@+id/but1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加密"
android:onClick="cc"
/>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/but2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解密"
android:onClick="cc"
/>
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
4.主函数
public class MainActivity extends AppCompatActivity {
private TextView tv,tv2;
private EditText ed;
private Key publicKey,privateKey;
private RSAUtils rsaUtils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv= (TextView) findViewById(R.id.tv);
tv2= (TextView) findViewById(R.id.tv2);
ed= (EditText) findViewById(R.id.et);
try {
//解密用公钥 加密用私钥
Map<String, Object> keyPair = RSAUtils.genKeyPair();
//获取公钥
publicKey = RSAUtils.getPublicKey(keyPair);
//获取私钥
privateKey = RSAUtils.getPrivateKey(keyPair);
} catch (Exception e) {
e.printStackTrace();
}
}
public void cc(View view) throws Exception {
rsaUtils = new RSAUtils();//实例化工具类
switch (view.getId()) {
case R.id.but1:
//加密
String s = ed.getText().toString();
byte[] bytes = s.getBytes();
try {
//第一个参数是获取得到的私钥 第二个参数是你想要加密的内容
byte[] encrypt = rsaUtils.encrypt(privateKey, bytes);
String encode = Base64Helper.encode(encrypt);
tv.setText(encode);
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.but2:
//解密
String s1 = tv2.getText().toString();
byte[] bytes1 = s1.getBytes();
//第一个参数是获取得到的公钥 第二个参数是你想要解密的暗文
byte[] decrypt = rsaUtils.decrypt(publicKey, bytes1);
tv2.setText(new String(decrypt,0,decrypt.length));
break;
}
}