android - 如何在 Go 和 Android 之间使用 RSA
问题描述
我(1)在Go中创建公钥并将其发送给Android(2)android使用下面的代码加密它的数据以字符串类型发送到Go(3)去获取字符串数据并尝试解密它,但它不能.
我的围棋代码:
// DecryptWithPrivateKey decrypts data with private key
func DecryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) []byte {
plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, priv , ciphertext)
if err != nil {
log.Println(err)
}
return plaintext
}
.
.
.
so.On("serverpublic", func(msg string) {
mes := []byte(msg)
decbyte :=DecryptWithPrivateKey(data,pr)
str := fmt.Sprintf("%s", decbyte)
log.Println("encript data from Android ---->" , str)
})
安卓工作室代码:
public final static String chi="RSA/NONE/PKCS1Padding"; //RSA/ECB/PKCS1Padding
private static byte[] dec4golang(byte[] src) throws Exception {
Cipher cipher = Cipher.getInstance(chi);
cipher.init(Cipher.DECRYPT_MODE, serverrk);
return cipher.doFinal(src);
}
private static byte[] enc4golang(String text, PublicKey pubRSA) throws Exception{
Cipher cipher = Cipher.getInstance(chi);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes("UTF-8")); //i also advice you to use: .getBytes("UTF-8"); instead of data.getBytes();
}
public final static String enc4golang(String text){
try {
return byte2hex(enc4golang(text, serveruk));
// return enc4golang(text, serveruk).toString();
// return new String(enc4golang(text, serveruk), "UTF-8");
// return new String(enc4golang(text, serveruk), Charset.forName("utf-8"));
// return Base64.encodeToString(enc4golang(text, serveruk), Base64.DEFAULT);///nodejs
// return Base64Utils.encodeToString(enc4golang(text, serveruk));
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public static String byte2hex(byte[] b)
{
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n ++)
{
stmp = Integer.toHexString(b[n] & 0xFF);
if (stmp.length() == 1)
hs += ("0" + stmp);
else
hs += stmp;
}
return hs.toUpperCase();
}
我认为我的问题在于这些方面:
chi="RSA/NONE/PKCS1Padding"; //RSA/ECB/PKCS1填充
或者
返回 byte2hex(enc4golang(text, serveruk));
解决方案
我已经测试过它并且它有效。
在 Go 中我使用这个函数:
func rusdec(encryptedString string , privateKey string) (string, error) {
base64DecodeBytes, err := base64.StdEncoding.DecodeString(encryptedString)
if err != nil {
return "", err
}
privateKeyBlock, _ := pem.Decode([]byte(privateKey))
var pri *rsa.PrivateKey
pri, parseErr := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if parseErr != nil {
return "", parseErr
}
decryptedData, decryptErr := rsa.DecryptOAEP(sha1.New(), rand.Reader, pri, base64DecodeBytes, nil)
if decryptErr != nil {
return "", decryptErr
}
return string(decryptedData), nil
}
在 Android 工作室中:
public final static String chi="RSA/ECB/OAEPPadding";
公共最终静态字符串 RSA = "RSA";
私有最终静态int CRYPTO_BITS = 512;
public static PublicKey stringToPublicKeytoserver(String publicKeyString)
{
try {
if (publicKeyString.contains("-----BEGIN PUBLIC KEY-----") || publicKeyString.contains("-----END PUBLIC KEY-----"))
publicKeyString = publicKeyString.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");
publicKeyString = publicKeyString.replace("-----BEGIN PUBLIC KEY-----", "");
publicKeyString = publicKeyString.replace("-----END PUBLIC KEY-----", "");
byte[] keyBytes = Base64.decode(publicKeyString, Base64.DEFAULT);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
serveruk=keyFactory.generatePublic(spec);
return serveruk;
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace();
return null;
}
}
private static byte[] enc4golang(String text, PublicKey pubRSA) throws Exception{
Cipher cipher = Cipher.getInstance(chi);
cipher.init(Cipher.ENCRYPT_MODE, pubRSA);
return cipher.doFinal(text.getBytes("UTF-8")); //i also advice you to use: .getBytes("UTF-8"); instead of data.getBytes();
}
public final static String enc4golang(String text){
try {
return Base64.encodeToString(enc4golang(text, serveruk) ,Base64.DEFAULT); //send this string to golang
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
Go 的公钥和私钥:
const priPEM = `-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJBALEZ+CmY7YN7KWib5Oh0AuWqfHiq3aURV1WGaaBm+X43kF3RRGJd
HbVdOEb2+YoNyni+LD5CQ4R3T7/f0sePzv0CAwEAAQJAc0MAlSoXotPcjl2vrG4c
mJbNrcceu9i+a0Ywppl+VVsEPOnapMQsVM04BpJzFmi00S+Sxl0pO1oAX0pwX7Oq
4QIhAOcncV+SQYlOWoH/phOGkA3y5j0eO2uUfqrXJX0q6/+FAiEAxCMvlkSePzkn
EROwzJu8tpZrIB6CNZ5KKfhPW7Dj3xkCIEvW1w2iMLpZ6LwKInT5iz3oWb3ns1si
h0SJ/hTJBlD5AiAKEtyQ1TljeeX9xIsiFyWcIyGhZq+9XUHl4fEBfpZVkQIgMfrj
qLoCdQH1D5F69WUMYd0n36Xpmqf7L9yV0Ofkz1Y=
-----END RSA PRIVATE KEY-----`
const pubPEM = `-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALEZ+CmY7YN7KWib5Oh0AuWqfHiq3aUR
V1WGaaBm+X43kF3RRGJdHbVdOEb2+YoNyni+LD5CQ4R3T7/f0sePzv0CAwEAAQ==
-----END PUBLIC KEY-----`
推荐阅读
- python - 我们如何在 Django 中创建插件和 Play 架构?
- abap - 在同一个alv屏幕中显示多个表
- scala - 将 RDD 数据写入 avro 文件时出错
- html - 从两侧围绕图像/形状包装两列文本html css
- c++ - 如何从特定位置开始读取文件c ++
- drools - 如何使用java应用程序在本地执行drools kjar而不使用kie-server容器?
- ios - URLSession 不返回任何内容
- c - 您可以在指向数组的指针中打印内容吗?
- clockify - 检索 Clockify 工作区时出现错误 500
- ajax - 如何克服 REST API 中的超时?