Android에서 RSA 암호화에 의존하지 않음

전에 RSA 암호화에 대한 블로그를 게시 한 후 자기 성찰을 시작했습니다. 사람들은 백그라운드에서도 Java를 사용하므로 암호화 및 암호 해독에 의존 할 필요가 없습니다. 그래서 저는 Android 프로젝트에 백엔드 코드를 넣었는데 매우 부끄럽습니다.이 두 가지 패키지가 없습니다.

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

Sun,이 회사는 이전에 Java 회사가 아니 었습니까? 그래서 저는 변덕스럽고 새로운 자바 라이브러리를 만들었습니다.

그래서 우리의 단계는 이와 같습니다.

먼저 프로젝트에 새로운 자바 라이브러리를 생성합니다. 새로운 모듈을 생성 할 때 사용자가 선택할 수 있습니다. 일반적으로 Android 라이브러리를 선택합니다. 이번에는 자바 라이브러리를 선택합니다. 새 패키지를 만든 후에는 암호화 및 해독하려는 패키지가이 클래스에 의존하도록하는 것을 잊지 마십시오.

그런 다음이 자바 라이브러리에 다음 클래스를 추가합니다.

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);
    }
}

이번에는 종속성 테스트도 통과했습니다.

그런 다음 암호화 및 복호화하려는 Android 라이브러리로 돌아갑니다.

지난번에 작성한 것과 비슷한 인터페이스를 먼저 작성해 봅시다.

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

그런 다음이 인터페이스에 해당하는 활동에 다음 코드를 작성합니다.

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();
                }
            }
        });
    }
}

보시다시피 우선

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

이 두 속성은 암호화 및 복호화시 사용해야하기 때문에 전역 적으로 배치되므로이 두 값은 한 번 생성 한 후에는 생성되지 않으며 하나는 Android 및 백그라운드에 저장됩니다. 공개 키 암호화, 개인 키 해독. 클라이언트 측 암호화와 서버 측 암호 해독 모두라면 클라이언트는 공개 키를, 서버는 개인 키를 가져옵니다. 그러나 양방향 인 경우 둘 다 암호화 및 해독되어야하며 둘 다 있어야합니다. 그런 다음 입력 상자를 사용하여 값을 할당하여 시뮬레이션 된 암호화 된 데이터의 전송을 실현합니다.

이러한 방식으로 데이터의 RSA 암호화 및 복호화를 실현했습니다.

추천

출처blog.csdn.net/weixin_38322371/article/details/115065498