編輯:關於Android編程
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 {
public AliasAdapter(Context context) {
// 使用適當的布局來顯示生成的密鑰
super(context, android.R.layout.simple_list_item_single_choice);
}
// 更新數據
public void setAliases(List 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> {
@Override
protected Enumeration doInBackground(Void... params) {
try {
// 創建KeyStore實例
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
// 創建空 keystore,或者不能從流中初始化 keystore,則傳遞 null 作為 stream 的參數
ks.load(null);
// 列出此 keystore 的所有別名
Enumeration aliases = ks.aliases();
return aliases;
} catch (Exception e) {
Log.w(TAG, "Could not list keys", e);
return null;
}
}
@Override
protected void onPostExecute(Enumeration result) {
List aliases = new ArrayList();
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 {
@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 {
@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 {
@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 {
@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;
}
}
}
—-布局文件——
ScrollView和ListView這兩個控件想必大家都不會陌生,但是這兩者嵌套使用的時候就會出現麻煩。比如,我們如果想在ListView下面添加其他的布局或者控件,然
電腦版qq能夠創建討論組,那手機qq呢?答案是肯定的,手機qq討論組怎麼建?手機qq討論組怎麼刪人?下面我們就來看看相關的操作吧!手機qq討論組怎麼建1、首
<?xml version=. encoding=UTF-?><RelativeLayout xmlns:android=http://
聯想旗下的控股品牌ZUK發布了新一代旗艦機ZUK Z2 Pro,那麼有網友就關心ZUK Z2 Pro有沒有NFC。NFC隨著指紋支付和APPLE PAY的盛