Android: AndroidKeyStore 非对称RSA加密解密
2017-10-14 22:02
399 查看
效果:
生成RSA秘钥工具类:AndroidKeyStoreRSAUtils
执行操作
更多加密方式DEMO请查看:https://gitee.com/huangxiaoguo/androidGeZhongJiaMiZongJie
更多加密方式博文请查看:http://blog.csdn.net/huangxiaoguo1/article/details/78043354
加密使用的是RSA加密,并把秘钥保存在androidKeyStore中,这样就保险,更加保障了我们的秘钥安全
生成RSA秘钥工具类:AndroidKeyStoreRSAUtils
package tsou.com.encryption.AndroidKeyStoreRSA; import android.content.Context; import android.os.Build; import android.security.KeyPairGeneratorSpec; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; import android.support.annotation.RequiresApi; import android.util.Log; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.UnrecoverableEntryException; import java.security.cert.CertificateException; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import javax.crypto.Cipher; import javax.security.auth.x500.X500Principal; import tsou.com.encryption.aescbc.Base64Decoder; import tsou.com.encryption.androidkeystoresign.SecurityConstants; public class AndroidKeyStoreRSAUtils { public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式 public static final int DEFAULT_KEY_SIZE = 2048;//秘钥默认长度 public static final byte[] DEFAULT_SPLIT = "#HUANGXIAOGUO#".getBytes(); // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密 public static final int DEFAULT_BUFFERSIZE = (DEFAULT_KEY_SIZE / 8) - 11;// 当前秘钥支持加密的最大字节数 /** * 自己给你的别名,方便在keystore中查找秘钥 */ public static final String SAMPLE_ALIAS = "xiaoGuoKey"; /** * 自己给你的别名 就是SAMPLE_ALIAS */ private static String mAlias = null; public static void setAlias(String alias) { mAlias = alias; } /** * 创建一个公共和私人密钥,并将其存储使用Android密钥存储库中,因此,只有 * 这个应用程序将能够访问键。 * * @param context * @throws InvalidAlgorithmParameterException * @throws NoSuchProviderException * @throws NoSuchAlgorithmException */ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) public static KeyPair generateRSAKeyPair(Context context) throws InvalidAlgorithmParameterException, NoSuchProviderException, NoSuchAlgorithmException { setAlias(SAMPLE_ALIAS); //创建一个开始和结束时间,有效范围内的密钥对才会生成。 Calendar start = new GregorianCalendar(); Calendar end = new GregorianCalendar(); end.add(Calendar.YEAR, 1);//往后加一年 AlgorithmParameterSpec spec; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { //使用别名来检索的key 。这是一个key 的key ! spec = new KeyPairGeneratorSpec.Builder(context) //使用别名来检索的关键。这是一个关键的关键! .setAlias(mAlias) // 用于生成自签名证书的主题 X500Principal 接受 RFC 1779/2253的专有名词 .setSubject(new X500Principal("CN=" + mAlias)) //用于自签名证书的序列号生成的一对。 .setSerialNumber(BigInteger.valueOf(1337)) // 签名在有效日期范围内 .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build(); } else { //Android 6.0(或者以上)使用KeyGenparameterSpec.Builder 方式来创建, // 允许你自定义允许的的关键属性和限制 spec = new KeyGenParameterSpec.Builder(mAlias, KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setKeySize(DEFAULT_KEY_SIZE) .setUserAuthenticationRequired(false) .setCertificateSubject(new X500Principal("CN=" + mAlias)) //, KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA224, KeyProperties.DIGEST_SHA384, // KeyProperties.DIGEST_SHA512, KeyProperties.DIGEST_MD5) .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1) .setCertificateNotBefore(start.getTime()) .setCertificateNotAfter(end.getTime()) .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1) .build(); } KeyPairGenerator kpGenerator = KeyPairGenerator .getInstance(SecurityConstants.TYPE_RSA, SecurityConstants.KEYSTORE_PROVIDER_ANDROID_KEYSTORE); kpGenerator.initialize(spec); KeyPair kp = kpGenerator.generateKeyPair(); return kp; } /** * 用公钥对字符串进行加密 * * @param data 原文 */ public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 加密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.ENCRYPT_MODE, keyPublic); return cp.doFinal(data); } /** * 私钥加密 * * @param data 待加密数据 * @param privateKey 密钥 * @return byte[] 加密数据 */ public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception { // 得到私钥 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey); KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA); PrivateKey keyPrivate = kf.generatePrivate(keySpec); // 数据加密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.ENCRYPT_MODE, keyPrivate); return cipher.doFinal(data); } /** * 公钥解密 * * @param data 待解密数据 * @param publicKey 密钥 * @return byte[] 解密数据 */ public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception { // 得到公钥 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey); KeyFactory kf = KeyFactory.getInstance(SecurityConstants.TYPE_RSA); PublicKey keyPublic = kf.generatePublic(keySpec); // 数据解密 Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING); cipher.init(Cipher.DECRYPT_MODE, keyPublic); return cipher.doFinal(data); } /** * 使用私钥进行解密 */ public static byte[] decryptByPrivateKey(byte[] encrypted) throws Exception { KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); if (mAlias == null) { setAlias(SAMPLE_ALIAS); } //从Android加载密钥对密钥存储库中 KeyStore.Entry entry = ks.getEntry(mAlias, null); if (entry == null) { return null; } if (!(entry instanceof KeyStore.PrivateKeyEntry)) { return null; } PrivateKey keyPrivate = ((KeyStore.PrivateKeyEntry) entry).getPrivateKey(); // 解密数据 Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING); cp.init(Cipher.DECRYPT_MODE, keyPrivate); byte[] arr = cp.doFinal(encrypted); return arr; } /** * 用公钥对字符串进行分段加密 */ public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception { int dataLen = data.length; if (dataLen <= DEFAULT_BUFFERSIZE) { return encryptByPublicKey(data, publicKey); } List<Byte> allBytes = new ArrayList<Byte>(2048); int bufIndex = 0; int subDataLoop = 0; byte[] buf = new byte[DEFAULT_BUFFERSIZE]; for (int i = 0; i < dataLen; i++) { buf[bufIndex] = data[i]; if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) { subDataLoop++; if (subDataLoop != 1) { for (byte b : DEFAULT_SPLIT) { allBytes.add(b); } } byte[] encryptBytes = encryptByPublicKey(buf, publicKey); for (byte b : encryptBytes) { allBytes.add(b); } bufIndex = 0; if (i == dataLen - 1) { buf = null; } else { buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)]; } } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 分段加密 * * @param data 要加密的原始数据 * @param privateKey 秘钥 */ public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception { int dataLen = data.length; if (dataLen <= DEFAULT_BUFFERSIZE) { return encryptByPrivateKey(data, privateKey); } List<Byte> allBytes = new ArrayList<Byte>(2048); int bufIndex = 0; int subDataLoop = 0; byte[] buf = new byte[DEFAULT_BUFFERSIZE]; for (int i = 0; i < dataLen; i++) { buf[bufIndex] = data[i]; if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) { subDataLoop++; if (subDataLoop != 1) { for (byte b : DEFAULT_SPLIT) { allBytes.add(b); } } byte[] encryptBytes = encryptByPrivateKey(buf, privateKey); for (byte b : encryptBytes) { allBytes.add(b); } bufIndex = 0; if (i == dataLen - 1) { buf = null; } else { buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)]; } } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 公钥分段解密 * * @param encrypted 待解密数据 * @param publicKey 密钥 */ public static byte[] decryptByPublicKeyForSpilt(byte[] encrypted, byte[] publicKey) throws Exception { int splitLen = DEFAULT_SPLIT.length; if (splitLen <= 0) { return decryptByPublicKey(encrypted, publicKey); } int dataLen = encrypted.length; List<Byte> allBytes = new ArrayList<Byte>(1024); int latestStartIndex = 0; for (int i = 0; i < dataLen; i++) { byte bt = encrypted[i]; boolean isMatchSplit = false; if (i == dataLen - 1) { // 到data的最后了 byte[] part = new byte[dataLen - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPublicKey(part, publicKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } else if (bt == DEFAULT_SPLIT[0]) { // 这个是以split[0]开头 if (splitLen > 1) { if (i + splitLen < dataLen) { // 没有超出data的范围 for (int j = 1; j < splitLen; j++) { if (DEFAULT_SPLIT[j] != encrypted[i + j]) { break; } if (j == splitLen - 1) { // 验证到split的最后一位,都没有break,则表明已经确认是split段 isMatchSplit = true; } } } } else { // split只有一位,则已经匹配了 isMatchSplit = true; } } if (isMatchSplit) { byte[] part = new byte[i - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPublicKey(part, publicKey); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 使用私钥分段解密 */ public static byte[] decryptByPrivateKeyForSpilt(byte[] encrypted) throws Exception { int splitLen = DEFAULT_SPLIT.length; if (splitLen <= 0) { return decryptByPrivateKey(encrypted); } int dataLen = encrypted.length; List<Byte> allBytes = new ArrayList<Byte>(1024); int latestStartIndex = 0; for (int i = 0; i < dataLen; i++) { byte bt = encrypted[i]; boolean isMatchSplit = false; if (i == dataLen - 1) { // 到data的最后了 byte[] part = new byte[dataLen - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPrivateKey(part); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } else if (bt == DEFAULT_SPLIT[0]) { // 这个是以split[0]开头 if (splitLen > 1) { if (i + splitLen < dataLen) { // 没有超出data的范围 for (int j = 1; j < splitLen; j++) { if (DEFAULT_SPLIT[j] != encrypted[i + j]) { break; } if (j == splitLen - 1) { // 验证到split的最后一位,都没有break,则表明已经确认是split段 isMatchSplit = true; } } } } else { // split只有一位,则已经匹配了 isMatchSplit = true; } } if (isMatchSplit) { byte[] part = new byte[i - latestStartIndex]; System.arraycopy(encrypted, latestStartIndex, part, 0, part.length); byte[] decryptPart = decryptByPrivateKey(part); for (byte b : decryptPart) { allBytes.add(b); } latestStartIndex = i + splitLen; i = latestStartIndex - 1; } } byte[] bytes = new byte[allBytes.size()]; { int i = 0; for (Byte b : allBytes) { bytes[i++] = b.byteValue(); } } return bytes; } /** * 通过字符串生成私钥,转换服务器传递过来的私钥 */ public static PrivateKey getPrivateKey(String privateKeyData) { PrivateKey privateKey = null; try { byte[] decodeKey = Base64Decoder.decodeToBytes(privateKeyData); PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//创建x509证书封装类 KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA privateKey = keyFactory.generatePrivate(x509);//生成私钥 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return privateKey; } /** * 通过字符串生成公钥,转换服务器传递过来的公钥 */ public static PublicKey getPublicKey(String publicKeyData) { PublicKey publicKey = null; try { byte[] decodeKey = Base64Decoder.decodeToBytes(publicKeyData); X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(x509); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } return publicKey; } /** * 判断是否创建过秘钥 * * @return * @throws KeyStoreException * @throws CertificateException * @throws NoSuchAlgorithmException * @throws IOException * @throws UnrecoverableEntryException */ public static boolean isHaveKeyStore() { try { KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); if (mAlias == null) { setAlias(SAMPLE_ALIAS); } //从Android加载密钥对密钥存储库中 KeyStore.Entry entry = ks.getEntry(mAlias, null); if (entry == null) { return false; } } catch (KeyStoreException e) { e.printStackTrace(); return false; } catch (CertificateException e) { e.printStackTrace(); return false; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } catch (UnrecoverableEntryException e) { e.printStackTrace(); return false; } return true; } /** * 获得本地AndroidKeyStore中的公钥 * * @return */ public static PublicKey getLocalPublicKey() { try { KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); ks.load(null); if (mAlias == null) { setAlias(SAMPLE_ALIAS); } //从Android加载密钥对密钥存储库中 KeyStore.Entry entry = ks.getEntry(mAlias, null); if (entry == null) { return null; } if (!(entry instanceof KeyStore.PrivateKeyEntry)) { return null; } PublicKey publicKey = ((KeyStore.PrivateKeyEntry) entry).getCertificate().getPublicKey(); return publicKey; } catch (KeyStoreException e) { e.printStackTrace(); return null; } catch (CertificateException e) { e.printStackTrace(); return null; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } catch (UnrecoverableEntryException e) { e.printStackTrace(); return null; } } }
package tsou.com.encryption.androidkeystoresign; public class SecurityConstants { public static final String KEYSTORE_PROVIDER_ANDROID_KEYSTORE = "AndroidKeyStore"; public static final String TYPE_RSA = "RSA"; public static final String TYPE_DSA = "DSA"; public static final String TYPE_BKS = "BKS"; public static final String SIGNATURE_SHA256withRSA = "SHA256withRSA"; public static final String SIGNATURE_SHA512withRSA = "SHA512withRSA"; }
执行操作
package tsou.com.encryption.activity.AndroidKeyStoreRSA; import android.app.Activity; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.interfaces.RSAPublicKey; import tsou.com.encryption.AndroidKeyStoreRSA.AndroidKeyStoreRSAUtils; import tsou.com.encryption.R; import tsou.com.encryption.aescbc.Base64Decoder; import tsou.com.encryption.aescbc.Base64Encoder; /** * 非对称RSA加密解密 * <p> * <p> * 一、什么是Rsa加密? * <p> * RSA算法是最流行的公钥密码算法,使用长度可以变化的密钥。 * RSA是第一个既能用于数据加密也能用于数字签名的算法。 * RSA算法原理如下: * 1.随机选择两个大质数p和q,p不等于q,计算N=pq; * 2.选择一个大于1小于N的自然数e,e必须与(p-1)(q-1)互素。 * 3.用公式计算出d:d×e = 1 (mod (p-1)(q-1)) 。 * 4.销毁p和q。 * 最终得到的N和e就是“公钥”,d就是“私钥”,发送方使用N去加密数据,接收方只有使用d才能解开数据内容。 * RSA的安全性依赖于大数分解,小于1024位的N已经被证明是不安全的,而且由于RSA算法进行的都是大数计算, * 使得RSA最快的情况也比DES慢上倍,这是RSA最大的缺陷,因此通常只能用于加密少量数据或者加密密钥, * 但RSA仍然不失为一种高强度的算法。 * <p> * <p> * 二、app与后台的tokenRSA加密登录认证与安全方式 * <p> * 客户端向服务器第一次发起登录请求(不传输用户名和密码)。 * <p> * 服务器利用RSA算法产生一对公钥和私钥。并保留私钥, 将公钥发送给客户端。 * <p> * 客户端收到公钥后, 加密用户密码,向服务器发送用户名和加密后的用户密码; * 同时另外产生一对公钥和私钥,自己保留私钥, 向服务器发送公钥; * 于是第二次登录请求传输了用户名和加密后的密码以及客户端生成的公钥。 * <p> * 服务器利用保留的私钥对密文进行解密,得到真正的密码。 经过判断, * 确定用户可以登录后,生成sessionId和token,同时利用客户端发送的公钥,对token进行加密。 * 最后将sessionId和加密后的token返还给客户端。 * <p> * 客户端利用自己生成的私钥对token密文解密, 得到真正的token。 * <p> * 三、博客地址 http://blog.csdn.net/huangxiaoguo1/article/details/78031798 */ public class AndroidKeyStoreRSAActivity extends AppCompatActivity implements View.OnClickListener { private EditText encryptionContext; private Button encryption; private TextView tvEncryption; private Button decode; private TextView tvDecode; private Activity mActivity; private Context mContext; private RSAPublicKey publicKey; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aes); mActivity = this; mContext = this; encryptionContext = (EditText) findViewById(R.id.et_encryption_context); encryption = (Button) findViewById(R.id.btn_encryption); tvEncryption = (TextView) findViewById(R.id.tv_encryption); decode = (Button) findViewById(R.id.btn_decode); tvDecode = (TextView) findViewById(R.id.tv_decode); encryption.setText("公钥加密"); decode.setText("私钥解密"); initListener(); } /** * 在应用安装后第一次运行时,生成一个随机密钥,并存入 KeyStore * 当你想存储一个数据,便从 KeyStore 中取出之前生成的随机密钥,对你的数据进行加密, * 加密完成后,已完成加密的数据可以随意存储在任意地方,比如 SharePreferences, * 此时即使它被他人读取到,也无法解密出你的原数据,因为他人取不到你的密钥 * 当你需要拿到你的原数据,只需要从 SharePreferences 中读取你加密后的数据, * 并从 KeyStore 取出加密密钥,使用加密密钥对 “加密后的数据” 进行解密即可 */ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (AndroidKeyStoreRSAUtils.isHaveKeyStore()) {//是否有秘钥 publicKey = (RSAPublicKey) AndroidKeyStoreRSAUtils.getLocalPublicKey(); if (publicKey != null) { Toast.makeText(mContext, "已经生成过密钥对", Toast.LENGTH_SHORT).show(); return; } } try {//在项目中放在application或启动页中 KeyPair keyPair = AndroidKeyStoreRSAUtils.generateRSAKeyPair(mContext); // 公钥 publicKey = (RSAPublicKey) keyPair.getPublic(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } private void initListener() { encryption.setOnClickListener(this); decode.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_encryption://公钥加密 //获取客户端公钥的base64编码的String,登录时将公钥传递给后台 // String localPublicKey = EncodeUtils.base64Encode2String(publicKey.getEncoded()); String encryptionString = encryptionContext.getText().toString().trim(); if (TextUtils.isEmpty(encryptionString)) { Toast.makeText(mContext, "请输入加密内容", Toast.LENGTH_SHORT).show(); return; } try { byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKeyForSpilt(encryptionString.getBytes(), publicKey.getEncoded()); // byte[] encryptBytes = AndroidKeyStoreRSAUtils.encryptByPublicKey(encryptionString.getBytes(), // publicKey.getEncoded()); String encryStr = Base64Encoder.encode(encryptBytes); tvEncryption.setText(encryStr); } catch (Exception e) { e.printStackTrace(); } break; case R.id.btn_decode://私钥解密 String decodeString = tvEncryption.getText().toString().trim(); if (TextUtils.isEmpty(decodeString)) { Toast.makeText(mContext, "请先加密", Toast.LENGTH_SHORT).show(); return; } try { byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKeyForSpilt( Base64Decoder.decodeToBytes(decodeString)); // byte[] decryptBytes = AndroidKeyStoreRSAUtils.decryptByPrivateKey( // Base64Decoder.decodeToBytes(decodeString)); tvDecode.setText(new String(decryptBytes)); } catch (Exception e) { e.printStackTrace(); } break; } } }
更多加密方式DEMO请查看:https://gitee.com/huangxiaoguo/androidGeZhongJiaMiZongJie
更多加密方式博文请查看:http://blog.csdn.net/huangxiaoguo1/article/details/78043354
相关文章推荐
- android RSA加密 解密 非对称可逆加密
- Android安全之非对称加密RSA密钥生成、加密、解密
- Java对称与非对称加密解密,AES与RSA
- python 加密 解密 签名 验证签名 公钥 私钥 非对称加密 RSA
- openssl RSA非对称加密解密
- Java对称与非对称加密解密,AES与RSA
- [置顶] Android 中 非对称(RSA)加密和对称(AES)加密
- Android RSA加密解密
- Android RSA加密解密
- Android 中 非对称(RSA)加密和对称(AES)加密
- [置顶] 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- Android RSA加密解密实现
- DES、RSA(分段加解密) Android中常用的两种加密方式
- RSA加密、解密、签名(非对称加密)
- CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
- Android RSA加密解密
- RSA非对称加密,使用OpenSSL生成证书,iOS加密,java解密
- android、ios与服务器端php使用rsa加密解密通讯
- Android RSA加密解密算法解析
- Android RSA加密解密