전에 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 암호화 및 복호화를 실현했습니다.