Sin dependencia del cifrado RSA en Android

Publiqué un blog sobre el cifrado RSA antes, y luego comencé a reflexionar sobre mí mismo: la gente también usa Java en segundo plano, por lo que no necesitan depender del cifrado y descifrado, por qué lo necesito. Así que puse el código de backend en nuestro proyecto de Android, lo cual es muy vergonzoso. No tengo estos dos paquetes.

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

Sun, ¿no es una empresa de Java antes? Así que tuve un capricho, creé una nueva biblioteca de Java y estaba hecho.

Entonces nuestros pasos son así.

En primer lugar, creamos una nueva biblioteca java en el proyecto. Cuando creamos un nuevo módulo, te dejaremos elegir. Normalmente elegimos la biblioteca de Android. Esta vez elegimos la biblioteca java. Después de crear uno nuevo, no olvide dejar que el paquete que queremos cifrar y descifrar dependa de esta clase.

Luego agregamos la siguiente clase a esta biblioteca java

import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 加密工具类
 * @author WaterWood
 */
public class RSAUtil {
    //生成秘钥对
    public static KeyPair getKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        return keyPair;
    }

    //获取公钥(Base64编码)
    public static String getPublicKey(KeyPair keyPair){
        PublicKey publicKey = keyPair.getPublic();
        byte[] bytes = publicKey.getEncoded();
        return byte2Base64(bytes);
    }

    //获取私钥(Base64编码)
    public static String getPrivateKey(KeyPair keyPair){
        PrivateKey privateKey = keyPair.getPrivate();
        byte[] bytes = privateKey.getEncoded();
        return byte2Base64(bytes);
    }

    //将Base64编码后的公钥转换成PublicKey对象
    public static PublicKey string2PublicKey(String pubStr) throws Exception{
        byte[] keyBytes = base642Byte(pubStr);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    //将Base64编码后的私钥转换成PrivateKey对象
    public static PrivateKey string2PrivateKey(String priStr) throws Exception{
        byte[] keyBytes = base642Byte(priStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    //公钥加密
    public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] bytes = cipher.doFinal(content);
        return bytes;
    }

    //私钥解密
    public static byte[] privateDecrypt(byte[] content, PrivateKey privateKey) throws Exception{
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] bytes = cipher.doFinal(content);
        return bytes;
    }

    //字节数组转Base64编码
    public static String byte2Base64(byte[] bytes){
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(bytes);
    }

    //Base64编码转字节数组
    public static byte[] base642Byte(String base64Key) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        return decoder.decodeBuffer(base64Key);
    }
}

Esta vez incluso pasé la prueba de dependencia.

Luego regrese a la biblioteca de Android que queremos cifrar y descifrar.

Primero escribamos una interfaz, que es similar a la que escribimos la última vez

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">
    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入文字"/>
    <Button
        android:id="@+id/bt_jiam"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="加密"/>
    <Button
        android:id="@+id/bt_jiem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="解密"/>

    <Button
        android:id="@+id/bt_scmyd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="生成密钥对"/>
</LinearLayout>

Luego escriba el siguiente código en la Actividad correspondiente a esta interfaz

public class MainActivity extends AppCompatActivity {

    private EditText et;
    private Button bt_jiam;
    private Button bt_jiem;
    private Button bt_scmyd;

    private String publicKeyStr;//公钥给客户端
    private String privateKeyStr;//私钥服务端

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et = findViewById(R.id.et);
        bt_jiam = findViewById(R.id.bt_jiam);
        bt_jiem = findViewById(R.id.bt_jiem);
        bt_scmyd = findViewById(R.id.bt_scmyd);
        bt_jiam.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //加密
                //注意:
                try {
                    //获取要加密的内容
                    String message = et.getText().toString().trim();
                    //将Base64编码后的公钥转换成PublicKey对象
                    PublicKey publicKey = RSAUtil.string2PublicKey(publicKeyStr);
                    //用公钥加密
                    byte[] publicEncrypt = RSAUtil.publicEncrypt(message.getBytes(), publicKey);
                    //加密后的内容Base64编码
                    String byte2Base64 = RSAUtil.byte2Base64(publicEncrypt);
                    et.setText(byte2Base64);
                    Log.i("看一看","公钥加密并Base64编码的结果:" + byte2Base64);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        bt_jiem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //解密
                try {
                    //将Base64编码后的私钥转换成PrivateKey对象
                    PrivateKey privateKey = RSAUtil.string2PrivateKey(privateKeyStr);
                    //加密后的内容Base64解码
                    byte[] base642Byte = RSAUtil.base642Byte(et.getText().toString().trim());
                    //用私钥解密
                    byte[] privateDecrypt = RSAUtil.privateDecrypt(base642Byte, privateKey);
                    //解密后的明文
                    et.setText(new String(privateDecrypt));
                    Log.i("看一看","解密后的明文: " + new String(privateDecrypt));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        bt_scmyd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //首先生成密钥对,这个可以在服务端进行,可以在客户端进行
                //不论谁进行,公钥给客户端,私钥给服务端,两个字符串分别存储在安全的地方
                try {
                    KeyPair keyPair = RSAUtil.getKeyPair();
                    publicKeyStr = RSAUtil.getPublicKey(keyPair);
                    privateKeyStr = RSAUtil.getPrivateKey(keyPair);
                    Log.i("看一看","RSA公钥Base64编码:" + publicKeyStr);
                    Log.i("看一看","RSA私钥Base64编码:" + privateKeyStr);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Como puedes ver, en primer lugar

private String publicKeyStr;//公钥给客户端
private String privateKeyStr;//私钥服务端

Estos dos atributos se colocan globalmente porque necesitamos usarlos al cifrar y descifrar, por lo que estos dos valores no se generan después de que los generamos una vez, y uno se guarda en Android y en segundo plano. Cifrado de clave pública, descifrado de clave privada. Si somos tanto el cifrado del lado del cliente como el descifrado del lado del servidor, entonces el cliente toma la clave pública y el servidor toma la clave privada. Pero si es bidireccional, ambos deben estar cifrados y descifrados, entonces necesita tener ambos. Luego usamos el cuadro de entrada para asignar valores para realizar la transmisión de datos encriptados simulados.

De esta manera, hemos realizado el cifrado y descifrado RSA de un dato.

Supongo que te gusta

Origin blog.csdn.net/weixin_38322371/article/details/115065498
Recomendado
Clasificación