相关资料学习:http://blog.csdn.net/innost/article/details/44081147
public class KeyStoreUsage extends Activity implements OnClickListener {
private static final String TAG = "LDM_KEYSTORE";
// KeyStore类用于密钥和证书的存储设施
KeyStore mKeyStore;
// 适配器
AliasAdapter mAdapter;
// 生成密钥对的tton
Button mGenerateButton;
// 生成签名的button
Button mSignButton;
// 核实签名的Button
Button mVerifyButton;
// 删除签名的on
Button mDeleteButton;
// 签名明文显示
EditText mPlainText;
// 保存签名文本字段
EditText mCipherText;
// 选中的签名
private String mSelectedAlias;
private ListView listview;
private EditText aliasInput;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.keystore_usage);
initViews();
initEvents();
mAdapter = new AliasAdapter(getApplicationContext());
listview.setAdapter(mAdapter);
// 更新密钥数据
updateKeyList();
}
/**
* 初始化控件
*
* @description:
* @author ldm
* @date 2016-7-20 下午2:45:06
*/
private void initViews() {
mVerifyButton = (Button) findViewById(R.id.verify_button);
aliasInput = (EditText) findViewById(R.id.entry_name);
mGenerateButton = (Button) findViewById(R.id.generate_button);
listview = (ListView) findViewById(R.id.entries_list);
mSignButton = (Button) findViewById(R.id.sign_button);
mCipherText = (EditText) findViewById(R.id.ciphertext);
mPlainText = (EditText) findViewById(R.id.plaintext);
mDeleteButton = (Button) findViewById(R.id.delete_button);
}
/**
*
* @descripton:初始化控件监听事件
* @author ldm
* @date 2016-7-20 下午2:45:37
*/
private void initEvents() {
mVerifyButton.setOnClickListener(this);
mGenerateButton.setOnClickListener(this);
mSignButton.setOnClickListener(this);
mDeleteButton.setOnClickListener(this);
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
mSelectedAlias = mAdapter.getItem(position);
// 选中已经存在的数据,则可以进行相应操作
setKeyActionButtonsEnabled(true);
}
});
}
/**
* 已经生成密钥的数据适配器
*
* @description:
* @author ldm
* @date 2016-7-20 下午3:26:23
*/
private class AliasAdapter extends ArrayAdapter<String> {
public AliasAdapter(Context context) {
// 使用适当的布局来显示生成的密钥
super(context, android.R.layout.simple_list_item_single_choice);
}
// 更新数据
public void setAliases(List<String> items) {
// 先清除数据
clear();
// 再添加数据
addAll(items);
// 刷新数据
notifyDataSetChanged();
}
}
private void updateKeyList() {
setKeyActionButtonsEnabled(false);
new UpdateKeyListTask().execute();
}
// 对已经存在的签名是否可以操作
private void setKeyActionButtonsEnabled(boolean enabled) {
mSignButton.setEnabled(enabled);
mVerifyButton.setEnabled(enabled);
mDeleteButton.setEnabled(enabled);
}
/**
* 更新数据,把密钥对应的别名展示在列表中
*
* @description:
* @author ldm
* @date 2016-7-20 下午4:13:48
*/
private class UpdateKeyListTask extends
AsyncTask<Void, Void, Enumeration<String>> {
@Override
protected Enumeration<String> doInBackground(Void... params) {
try {
// 创建KeyStore实例
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
// 创建空 keystore,或者不能从流中初始化 keystore,则传递 null 作为 stream 的参数
ks.load(null);
// 列出此 keystore 的所有别名
Enumeration<String> aliases = ks.aliases();
return aliases;
} catch (Exception e) {
Log.w(TAG, "Could not list keys", e);
return null;
}
}
@Override
protected void onPostExecute(Enumeration<String> result) {
List<String> aliases = new ArrayList<String>();
while (result.hasMoreElements()) {
aliases.add(result.nextElement());
}
// 把数据放入适配器中
mAdapter.setAliases(aliases);
}
}
/**
* 生成密钥的异步任务
*
* @description:
* @author ldm
* @date 2016-7-20 下午3:32:15
*/
@SuppressLint({ "TrulyRandom", "NewApi" })
private class GenerateTask extends AsyncTask<String, Void, Boolean> {
@SuppressLint("TrulyRandom")
@Override
protected Boolean doInBackground(String... params) {
// 获取到别名
final String alias = params[0];
try {
// 生成密钥库内的一个新条目用
Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.YEAR, 1);
Date end = cal.getTime();
// 使用RSA算法创建KeyPair
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA",
"AndroidKeyStore");
// 设置Keypair参数
// http://wear.techbrood.com/reference/android/security/KeyPairGeneratorSpec.html
kpg.initialize(new KeyPairGeneratorSpec.Builder(
getApplicationContext()).setAlias(alias)// 设置别名
.setStartDate(now).setEndDate(end)// 设置开始日期和结束日期(证书有效期)
.setSerialNumber(BigInteger.valueOf(1))// 设置序列与
.setSubject(new X500Principal("CN=test1")).build());// 设置用于生成密钥签名证书的主题
return true;
} catch (Exception e) {
Log.w(TAG, "Could not generate key", e);
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
// 更新数据
updateKeyList();
// 生成完成后,按钮恢复可用
mGenerateButton.setEnabled(true);
}
@Override
protected void onCancelled() {
mGenerateButton.setEnabled(true);
}
}
/**
* 异步任务进行签名
*
* @description:使用一个密钥的密钥库中的一些数据创建一个签名
* @author ldm
* @date 2016-7-20 下午3:34:27
*/
private class SignTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
final String alias = params[0];
final String dataString = params[1];
try {
byte[] data = dataString.getBytes();
// 创建KeyPair
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
// 获取别名对应地私钥
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
Log.w(TAG, "Not an instance of a PrivateKeyEntry");
return null;
}
// 获取签名
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(((PrivateKeyEntry) entry).getPrivateKey());
s.update(data);
byte[] signature = s.sign();
// 返回64位的签名数据
return Base64.encodeToString(signature, Base64.DEFAULT);
} catch (Exception e) {
Log.w(TAG, "Could not generate key", e);
return null;
}
}
@Override
protected void onPostExecute(String result) {
// 把签名生成的数据展示在EditText中
mCipherText.setText(result);
setKeyActionButtonsEnabled(true);
}
@Override
protected void onCancelled() {
mCipherText.setText("error!");
setKeyActionButtonsEnabled(true);
}
}
/**
* 对已经存在的签名密钥进行验证
*
* @description:
* @author ldm
* @date 2016-7-20 下午3:46:19
*/
private class VerifyTask extends AsyncTask<String, Void, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
final String alias = params[0];
final String dataString = params[1];
final String signatureString = params[2];
try {
byte[] data = dataString.getBytes();
byte[] signature;
try {
signature = Base64.decode(signatureString, Base64.DEFAULT);
} catch (IllegalArgumentException e) {
signature = new byte[0];
}
// 对签名进行验证
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
//获取别名对应密钥
KeyStore.Entry entry = ks.getEntry(alias, null);
if (!(entry instanceof PrivateKeyEntry)) {
Log.w(TAG, "Not an instance of a PrivateKeyEntry");
return false;
}
Signature s = Signature.getInstance("SHA256withRSA");
s.initVerify(((PrivateKeyEntry) entry).getCertificate());
s.update(data);
return s.verify(signature);
} catch (Exception e) {
Log.w(TAG, "Could not generate key", e);
return false;
}
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {// 验证成功,文字 是绿色
mCipherText.setTextColor(getResources().getColor(
R.color.solid_green));
} else {// 验证失败则文字显示红色
mCipherText.setTextColor(getResources().getColor(
R.color.solid_red));
}
setKeyActionButtonsEnabled(true);
}
@Override
protected void onCancelled() {
mCipherText.setText("error!");
setKeyActionButtonsEnabled(true);
mCipherText.setTextColor(getResources().getColor(
android.R.color.primary_text_dark));
}
}
/**
* 删除操作
*
* @description:
* @author ldm
* @date 2016-7-20 下午3:49:48
*/
private class DeleteTask extends AsyncTask<String, Void, Void> {
@Override
protected Void doInBackground(String... params) {
final String alias = params[0];
try {
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);
// 删除已经有的签名密钥
ks.deleteEntry(alias);
} catch (Exception e) {
Log.w(TAG, "Could not generate key", e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
updateKeyList();
}
@Override
protected void onCancelled() {
updateKeyList();
}
}
@Override
public void onClick(View v) {
final String alias = mSelectedAlias;
switch (v.getId()) {
case R.id.verify_button:
final String data = mPlainText.getText().toString();
final String signature = mCipherText.getText().toString();
if (alias != null) {
setKeyActionButtonsEnabled(false);
// 验证:生成的密钥别名,输入的别名与密钥进行校验
new VerifyTask().execute(alias, data, signature);
}
break;
case R.id.generate_button:
// 密钥别名
if (TextUtils.isEmpty(aliasInput.getText().toString())) {
// 输入为空时错误提示
aliasInput.setError(getResources().getText(
R.string.keystore_no_alias_error));
} else {
// 取消错误提示
aliasInput.setError(null);
mGenerateButton.setEnabled(false);
// 生成密钥
new GenerateTask().execute(aliasInput.getText().toString());
}
break;
case R.id.sign_button:
if (mPlainText.getText().toString() != null) {
setKeyActionButtonsEnabled(false);
new SignTask().execute(alias, mPlainText.getText().toString());
}
break;
case R.id.delete_button:
if (alias != null) {
setKeyActionButtonsEnabled(false);
new DeleteTask().execute(alias);
}
break;
}
}
}
—-布局文件——
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="6dip" >
<RelativeLayout
android:id="@+id/entries_list_group"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginBottom="12dp"
android:layout_weight="1" >
<TextView
android:id="@+id/entries_list_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="12dp"
android:text="已经生成的密钥对应的别名列表" />
<ListView
android:id="@+id/entries_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/entries_list_label"
android:layout_below="@+id/entries_list_label"
android:layout_marginBottom="12dp"
android:choiceMode="singleChoice" >
<requestFocus />
</ListView>
</RelativeLayout>
<RelativeLayout
android:id="@+id/sign_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:layout_marginTop="12dp" >
<TextView
android:id="@+id/key_ops_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="6dp"
android:text="对已经生成的密钥进行操作"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/plaintext_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/key_ops_header"
android:layout_below="@id/key_ops_header"
android:layout_marginLeft="6dp"
android:text="明码内容:" />
<EditText
android:id="@+id/plaintext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/plaintext_label"
android:layout_alignParentRight="true"
android:layout_below="@+id/key_ops_header"
android:layout_toRightOf="@id/plaintext_label"
android:ems="10"
android:maxLines="1" />
<TextView
android:id="@+id/ciphertext_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/plaintext_label"
android:layout_below="@+id/plaintext"
android:text="密钥内容:" />
<EditText
android:id="@+id/ciphertext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/ciphertext_label"
android:layout_alignParentRight="true"
android:layout_below="@+id/plaintext"
android:layout_toRightOf="@id/ciphertext_label"
android:maxLines="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/plaintext_label"
android:layout_below="@+id/ciphertext" >
<Button
android:id="@+id/sign_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="签名" />
<Button
android:id="@+id/verify_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="校验" />
<Button
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:text="删除" />
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/generate_group"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginTop="12dp" >
<TextView
android:id="@+id/generating_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="6dp"
android:text="通过输入别名生成密钥"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/entry_name_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/generating_header"
android:layout_below="@+id/generating_header"
android:layout_marginBottom="12dp"
android:layout_marginLeft="6dp"
android:text="输入别名:" />
<Button
android:id="@+id/generate_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/entry_name_label"
android:layout_below="@+id/entry_name"
android:text="生成密钥" />
<EditText
android:id="@+id/entry_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/entry_name_label"
android:layout_alignParentRight="true"
android:layout_marginBottom="12dp"
android:layout_toRightOf="@+id/entry_name_label"
android:ems="10" />
</RelativeLayout>
</LinearLayout>