Cifrado RSA en Android

La última vez que hablamos sobre un cifrado MD5, revisémoslo. Este es un método de cifrado unidireccional. Solo podemos permitir que la persona que intercepta nuestros datos no sepa cuál es nuestro contenido real, pero no podemos descifrarlo al revés. Generalmente utilizado para ocasiones de verificación de información. De lo que estoy hablando hoy es de algo que se puede cifrar y descifrar, y eso es el cifrado RSA.

El contenido después del cifrado RSA es una matriz de bytes y el contenido necesario para el descifrado también es una matriz de bytes. Pero si intenta convertir la matriz de bytes cifrada en una cadena, encontrará que está distorsionada. Entonces, cuando transferimos o guardamos, necesitamos transferir directamente la matriz de bytes, no intente convertirla en una cadena, de lo contrario habrá errores inesperados.

El código es el siguiente, para su referencia. He subido el paquete dependiente al recurso.

Clase de herramienta de cifrado RSAUtil.java

public class RSAUtil {
    private static final String TAG = "RSAUtil";
    private static final String Algorithm = "RSA";

    public static KeyPair generateKeyPair() throws Exception {
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(Algorithm,
                    new org.bouncycastle.jce.provider.BouncyCastleProvider());
            // 这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会降低
            final int KEY_SIZE = 1024;
            keyPairGen.initialize(KEY_SIZE, new SecureRandom());
            KeyPair keyPair = keyPairGen.generateKeyPair();
            return keyPair;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    //加密
    public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance(Algorithm,
                    new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();
            int outputSize = cipher.getOutputSize(data.length);
            int leavedSize = data.length % blockSize;
            int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
                    : data.length / blockSize;
            byte[] raw = new byte[outputSize * blocksSize];
            int i = 0;
            while (data.length - i * blockSize > 0) {
                if (data.length - i * blockSize > blockSize) {
                    cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
                } else {
                    cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
                }
                i++;
            }
            return raw;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    //解密
    public static byte[] decrypt(PrivateKey pk, byte[] raw) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance(Algorithm,
                    new org.bouncycastle.jce.provider.BouncyCastleProvider());
            cipher.init(cipher.DECRYPT_MODE, pk);
            int blockSize = cipher.getBlockSize();
            ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
            int j = 0;
            while (raw.length - j * blockSize > 0) {
                bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                j++;
            }
            return bout.toByteArray();
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }
}

diseño

<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>

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

    private KeyPair keyPair;//公钥私钥对
    private byte[] bytes;

    @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) {
                String content = et.getText().toString();
                try {
                    bytes =  RSAUtil.encrypt(keyPair.getPublic(),content.getBytes());
                    et.setText("");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        bt_jiem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    bytes =  RSAUtil.decrypt(keyPair.getPrivate(),bytes);
                    et.setText(new String(bytes));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        bt_scmyd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    keyPair = RSAUtil.generateKeyPair();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Al operar, primero debemos generar un par de claves. Entonces puede realizar operaciones de cifrado y descifrado. La operación de generar un par de claves se puede realizar en el lado del servidor. Luego empaquete el contenido serializado en nuestro extremo local, serialícelo en un archivo y empaquetelo en el apk.

Supongo que te gusta

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