RSA加密算法解析+数字签名验证

RSA加密算法


  • 此Demo实现以下这几个功能

密钥的显示

布局文件就不往出列了

1 . 生成公钥私钥
这是一个耗时操作,是通过随意选择两个大的质数经过一系列的复杂运算获得的,想了解算法自行百度,这里只说一下它如何使用!
case 的时候封装为一个方法

private void generateRsa() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //1.获取keyPareGenerator
                try {
                    KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
                    //2.进行初始化,长度
                    keyPairGenerator.initialize(1024);

                    //3.获取密码
                    KeyPair keyPair = keyPairGenerator.generateKeyPair();
                    //4.获取私钥
                    privateKey = keyPair.getPrivate();
                    publicKey = keyPair.getPublic();

                    //展示数据:
                    final byte[] privateKeyEncoded = privateKey.getEncoded();
                    final byte[] publicKeyEncoded = publicKey.getEncoded();

                    //将密钥保存,如果不需要可以省略
                    SharedPreferences sp = MainActivity.this.getSharedPreferences("config", MODE_PRIVATE);
                    SharedPreferences.Editor editor = sp.edit();
                    editor.putString("privateKey",Base64.encodeToString(privateKeyEncoded,Base64.DEFAULT));
                    editor.putString("publicKey",Base64.encodeToString(publicKeyEncoded,Base64.DEFAULT));
                    editor.commit();
//将获取到的内容显示到界面上
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            StringBuilder builder = new StringBuilder();
                            builder.append("私钥是:"+'\n');
                            builder.append(Base64.encodeToString(privateKeyEncoded,Base64.DEFAULT)+'\n');
                            builder.append("公钥是:"+'\n');
                            builder.append(Base64.encodeToString(publicKeyEncoded,Base64.DEFAULT)+'\n');

                            mResult.setText(builder.toString());
                        }
                    });

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

2 . RSA加密(私钥加密)

直接从缓存中获取,SharedPreferences

//全局的常量声明
private String data = "Google Home 或 Amazon Echo 值得买吗?";

case R.id.encrypt:
                //
                String privateKey = sp.getString("privateKey", null);
                byte[] decode = Base64.decode(privateKey, Base64.DEFAULT);
                try {
                    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                    //私钥字节数组转换成私钥
                    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decode);
                    PrivateKey privateKey1 = keyFactory.generatePrivate(keySpec);
                    String encrypt = encrypt(data, privateKey1, 0);
                    mResult.setText(encrypt);

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeySpecException e) {
                    e.printStackTrace();
                }
                break;

3 . RSA解密(公钥解密)

case R.id.decode:
                String publicKey = sp.getString("publicKey", null);
                byte[] decode1 = Base64.decode(publicKey, Base64.DEFAULT);
                try {
                    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decode1);
                    PublicKey publicKey1 = keyFactory.generatePublic(keySpec);

                    String data = mResult.getText().toString().trim();
                    String s = encrypt(data, publicKey1, 1);
                    mResult.setText(s);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeySpecException e) {
                    e.printStackTrace();
                }
                break;
  • encrypt(data, publicKey1, 1);
    该方法判断加密还是解密.
private String encrypt(String data, Key Key, int type) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            //设置密码
            switch (type) {
                case 0:
                    cipher.init(Cipher.ENCRYPT_MODE,Key);
                    break;
                case 1:
                    cipher.init(Cipher.DECRYPT_MODE,Key);
                    break;
            }
            //区分加密解密:
            switch (type) {
                case 0:
                    byte[] bytes = cipher.doFinal(data.getBytes());
                    byte[] encode = Base64.encode(bytes, Base64.DEFAULT);
                    String result = new String(encode);
                     return result;
                case 1:
                    byte[] decode = Base64.decode(data, Base64.DEFAULT);
                    byte[] doFinal = cipher.doFinal(decode);
                    String dResult = new String(doFinal);
                    return dResult;
            }
        }
        //这里注意抛异常
         return data;

4 . 数字签名

  • 数字签名使用私钥进行加密 MD5withRSA
  • 核心的方法:
    1.Signature.getInstance(“MD5withRSA”);初始化操作
    2.signature.initSign(privateKey); 使用私钥进行签名
    3.signature.update(data.getBytes()); 签名的数据
    4.byte[] sign = signature.sign();生成签名
    5.使用Base64编码否则传输的为乱码
case R.id.md5Rsa://数字签名,使用私钥进行
                try {
                    Signature signature = Signature.getInstance("MD5withRSA");
                    signature.initSign(privateKey);
                    signature.update(this.data.getBytes());
                    byte[] sign = signature.sign();//签名的数据
                    //将源文件和签名的数据一块发送给合作伙伴
                    mSignResult = Base64.encodeToString(sign, Base64.DEFAULT);
                    Log.d("flag", "----------------->rsa: 要传送给合作伙伴的数据: " +this.data+", 数字签名: "+mSignResult);
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (SignatureException e) {
                    e.printStackTrace();
                }
                break;

5 . 验证数字签名
- 核心方法
boolean verify = signature.verify();判断验证的结果

case R.id.md5vertify:
                try {
                    Signature signature = Signature.getInstance("MD5withRSA");
                    //数字验证,使用公钥
                    signature.initVerify(mKeyPairPublic);

                    //update,传递过来的源文件
                    signature.update(this.data.getBytes());

                    //对签名进行验证 mSignResult
                    boolean verify = signature.verify(Base64.decode(mSignResult, Base64.DEFAULT));
                    Log.d("flag", "---------->rsa: 验证结果: " +verify);

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (SignatureException e) {
                    e.printStackTrace();
                }
                break;
  • 最后结束程序将数据置空,减少内存的占用
@Override
    protected void onDestroy() {
        super.onDestroy();
        result = null;
        data = null;
    }

判断公钥-私钥是否匹配

//取出私钥
        //从sp中获取私钥
        String privateKey = sp.getString("privateKey", null);
        byte[] decode = Base64.decode(privateKey, Base64.DEFAULT);
        //私钥字节数组转换成私钥
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            //PKCS8EncodedKeySpec ---->对应RSA 私钥
            KeySpec keySpec = new PKCS8EncodedKeySpec(decode);

            mKeyPairPrivate = keyFactory.generatePrivate(keySpec);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        String publicKey =this.publicKey;

        byte[] decode1 = Base64.decode(publicKey, Base64.DEFAULT);
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            //X509EncodedKeySpec ----->RSA 公钥
            KeySpec keySpec = new X509EncodedKeySpec(decode1);
            mKeyPairPublic = keyFactory.generatePublic(keySpec);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值