Android中的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仍然不失为一种高强度的算法。

使用,看代码:

public class RSADemoActivity extends AppCompatActivity {
    private EditText editText ;
    private byte[] sign ;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView( R.layout.rsad_activity_layout);
        editText = (EditText) findViewById( R.id.resd_action_et) ;
    }


    /**
     * 生成秘钥对(公钥加密 , 私钥解密)
     * @param view
     */
    public void yaoshi(View view) throws Exception {
        //对应算法的密钥对生成器
        KeyPairGenerator kpg =  KeyPairGenerator.getInstance( "RSA" ) ;
        //生成密钥对
        KeyPair kp = kpg.generateKeyPair() ;
        //获取公钥匙(公钥匙加密使用)
        PublicKey publicKey = kp.getPublic() ;
        //获取私密钥匙(私密钥匙解密使用 )
        PrivateKey privateKey = kp.getPrivate() ;
        //以下代码用于保存key(保存公钥匙)
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"publickey.sys");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        oos.writeObject(publicKey);
        oos.flush() ;
        //保存私密钥匙
        file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"privatekey.sys");
        ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(file));
        oos1.writeObject(privateKey);
        oos1.flush();
    }

    /**
     *加密(公钥加密)
     * @param view
     */
    public void encode(View view) throws Exception {
        //获取公钥匙
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "publickey.sys" );
        PublicKey publicKey = (PublicKey) new ObjectInputStream( new FileInputStream( file)).readObject();
        //获取加密工具
        Cipher cipher = Cipher.getInstance("RSA") ;
        //初始化加密工具(这里是加密)
        cipher.init( Cipher.ENCRYPT_MODE , publicKey );
        //设置明文内容
        cipher.update(editText.getText().toString().getBytes());
        //得到密文
        byte[] bytes = cipher.doFinal();
        editText.setText(new String(Base64.encode(bytes,Base64.DEFAULT)));
    }

    /**
     * 解密
     * @param view
     */
    public void deCode(View view) throws Exception {
        //获取私钥匙
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "privatekey.sys" );
        PrivateKey privateKey = (PrivateKey) new ObjectInputStream( new FileInputStream( file)).readObject();
        //获取加密工具
        Cipher cipher = Cipher.getInstance("RSA") ;
        //初始化加密工具(这里是解密)
        cipher.init( Cipher.DECRYPT_MODE , privateKey ) ;
       //获取编辑框的内容
        String basestr = editText.getText().toString() ;
        //设置密文内容
        cipher.update(Base64.decode(basestr.getBytes(),Base64.DEFAULT));
        //得到明文
        byte[] bytes = cipher.doFinal() ;
        //把明文显示到编辑框上
        editText.setText(new String(bytes)) ;
    }

    /**
     * 生成签名(私钥签名)
     * @param view
     */
    public void make_sign(View view) throws Exception {
        //获取私钥匙(私钥签名)
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "privatekey.sys" );
        PrivateKey privateKey = (PrivateKey) new ObjectInputStream( new FileInputStream( file)).readObject();
        //初始化算法 ,获取对应算法的签名工具
        Signature signature = Signature.getInstance("SHA1WithRSA") ;
        //初始化签名工具
        signature.initSign( privateKey );
        //设置签名的内容
        signature.update( editText.getText().toString().getBytes() );
        //生成签名( 这个签名后的内容要保存下来,验证方要验证这个签名 , 要用同的签名的内容去验证签名)
        sign = signature.sign() ;
    }

    /**
     * 验证签名(共钥验证签名)
     * @param view
     */
    public void verify_sign(View view) throws Exception {
        //获取公钥匙
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "publickey.sys" );
        PublicKey publicKey = (PublicKey) new ObjectInputStream( new FileInputStream( file)).readObject();
        //初始化算法 ,获取对应算法的签名工具
        Signature signature = Signature.getInstance("SHA1WithRSA") ;
        //初始化验证签名工具
        signature.initVerify( publicKey );
        //设置要验证签名内容
        signature.update( editText.getText().toString().getBytes() );
        //验证签名
        boolean flag = signature.verify( sign );
        if( flag){
             System.out.println("验证签名成功");
        }else {
            System.out.println("验证签名失败");
        }
    }
}
xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/resd_action_et"
        android:layout_width="match_parent"
        android:layout_height="100dp"/>

    <Button
        android:onClick="yaoshi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="生成钥匙对"/>

    <Button
        android:onClick="encode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RESD加密"/>

    <Button
        android:onClick="deCode"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="RESD解密"/>

    <Button
        android:onClick="make_sign"
        android:text="生成Sha1WithRsa签名"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Button
        android:onClick="verify_sign"
        android:text="验证Sha1WithRsa签名"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

RSA加密算法,可逆的,加密使用的是共钥,解密使用的是私钥,所以先生成秘钥对

扫描二维码关注公众号,回复: 874469 查看本文章
/**
 * 生成秘钥对(公钥加密 , 私钥解密)
 * @param view
 */
public void yaoshi(View view) throws Exception {
    //对应算法的密钥对生成器
    KeyPairGenerator kpg =  KeyPairGenerator.getInstance( "RSA" ) ;
    //生成密钥对
    KeyPair kp = kpg.generateKeyPair() ;
    //获取公钥匙(公钥匙加密使用)
    PublicKey publicKey = kp.getPublic() ;
    //获取私密钥匙(私密钥匙解密使用 )
    PrivateKey privateKey = kp.getPrivate() ;
    //以下代码用于保存key(保存公钥匙)
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"publickey.sys");
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
    oos.writeObject(publicKey);
    oos.flush() ;
    //保存私密钥匙
    file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"privatekey.sys");
    ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(file));
    oos1.writeObject(privateKey);
    oos1.flush();
}
加密使用的是共钥:

/**
 *加密(公钥加密)
 * @param view
 */
public void encode(View view) throws Exception {
    //获取公钥匙
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "publickey.sys" );
    PublicKey publicKey = (PublicKey) new ObjectInputStream( new FileInputStream( file)).readObject();
    //获取加密工具
    Cipher cipher = Cipher.getInstance("RSA") ;
    //初始化加密工具(这里是加密)
    cipher.init( Cipher.ENCRYPT_MODE , publicKey );
    //设置明文内容
    cipher.update(editText.getText().toString().getBytes());
    //得到密文
    byte[] bytes = cipher.doFinal();
    editText.setText(new String(Base64.encode(bytes,Base64.DEFAULT)));
}
解密使用的是私钥:

/**
 * 解密
 * @param view
 */
public void deCode(View view) throws Exception {
    //获取私钥匙
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "privatekey.sys" );
    PrivateKey privateKey = (PrivateKey) new ObjectInputStream( new FileInputStream( file)).readObject();
    //获取加密工具
    Cipher cipher = Cipher.getInstance("RSA") ;
    //初始化加密工具(这里是解密)
    cipher.init( Cipher.DECRYPT_MODE , privateKey ) ;
   //获取编辑框的内容
    String basestr = editText.getText().toString() ;
    //设置密文内容
    cipher.update(Base64.decode(basestr.getBytes(),Base64.DEFAULT));
    //得到明文
    byte[] bytes = cipher.doFinal() ;
    //把明文显示到编辑框上
    editText.setText(new String(bytes)) ;
}

私钥生成签名:

/**
 * 生成签名(私钥签名)
 * @param view
 */
public void make_sign(View view) throws Exception {
    //获取私钥匙(私钥签名)
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "privatekey.sys" );
    PrivateKey privateKey = (PrivateKey) new ObjectInputStream( new FileInputStream( file)).readObject();
    //初始化算法 ,获取对应算法的签名工具
    Signature signature = Signature.getInstance("SHA1WithRSA") ;
    //初始化签名工具
    signature.initSign( privateKey );
    //设置签名的内容
    signature.update( editText.getText().toString().getBytes() );
    //生成签名( 这个签名后的内容要保存下来,验证方要验证这个签名 , 要用同的签名的内容去验证签名)
    sign = signature.sign() ;
}
使用共钥验证私钥生成的签名:

/**
 * 验证签名(共钥验证签名)
 * @param view
 */
public void verify_sign(View view) throws Exception {
    //获取公钥匙
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "publickey.sys" );
    PublicKey publicKey = (PublicKey) new ObjectInputStream( new FileInputStream( file)).readObject();
    //初始化算法 ,获取对应算法的签名工具
    Signature signature = Signature.getInstance("SHA1WithRSA") ;
    //初始化验证签名工具
    signature.initVerify( publicKey );
    //设置要验证签名内容
    signature.update( editText.getText().toString().getBytes() );
    //验证签名
    boolean flag = signature.verify( sign );
    if( flag){
         System.out.println("验证签名成功");
    }else {
        System.out.println("验证签名失败");
    }
}



猜你喜欢

转载自blog.csdn.net/xiaol206/article/details/71970636