RSA PKCS#1 加密¶
调用代理商登录相关接口时,密码不能明文传输。请使用平台提供的 RSA 公钥,按 PKCS#1 填充加密,再把密文编成 URL-Safe Base64 后写入请求体。
适用场景¶
- 调用 代理商同步账号到云平台、修改密码、获取一键登录码 时加密密码。
- 接收 密码变更通知 时,用您自己的私钥按同一算法解密
newPassword。
加密约定¶
| 项目 | 取值 |
|---|---|
| 算法 | RSA |
| 填充 | PKCS#1 v1.5(Java 中对应 RSA/ECB/PKCS1Padding) |
| 明文编码 | UTF-8 |
| 密文编码 | URL-Safe Base64,可去掉 = 填充 |
平台解密时兼容标准 Base64 与 URL-Safe Base64。建议按 URL-Safe 输出,避免 +、/ 在 JSON 或 URL 中被转义。
注意:调用平台接口时,必须使用平台提供的公钥。个人中心配置的公钥只用于平台回推密码,两把密钥不能混用。完整接入步骤见 自有平台接入一键登录。
平台 RSA 公钥¶
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC9kMNVuFE+2qnb1vXjlRmjKhd
HR0AEe3i/p0iQNwB082raTulbM2NNdlstG+otWweScbfxwdIj2zylVm31kdEt5yp
wOD4rzDq8MEK51R9wXLzPxPAbJK48occlTdfuh6hX2nK11Toe4D0GaMsE++SanE5
6/d49uXc/ZOrQeAk3QIDAQAB
-----END PUBLIC KEY-----
加密示例¶
以下示例将明文 ExamplePwd1 加密为请求体中的密文。请将公钥与明文替换为实际值。
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;
public class RsaPkcs1EncryptTest {
public static void main(String[] args) throws Exception {
String publicKeyPem = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC9kMNVuFE+2qnb1vXjlRmjKhd"
+ "HR0AEe3i/p0iQNwB082raTulbM2NNdlstG+otWweScbfxwdIj2zylVm31kdEt5yp"
+ "wOD4rzDq8MEK51R9wXLzPxPAbJK48occlTdfuh6hX2nK11Toe4D0GaMsE++SanE5"
+ "6/d49uXc/ZOrQeAk3QIDAQAB";
String plainText = "ExamplePwd1";
byte[] keyBytes = Base64.decodeBase64(publicKeyPem);
RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(keyBytes));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
String cipherText = Base64.encodeBase64URLSafeString(cipher.doFinal(plainText.getBytes("UTF-8")));
System.out.println(cipherText);
}
}
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"strings"
)
func main() {
publicKeyPem := `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC9kMNVuFE+2qnb1vXjlRmjKhd
HR0AEe3i/p0iQNwB082raTulbM2NNdlstG+otWweScbfxwdIj2zylVm31kdEt5yp
wOD4rzDq8MEK51R9wXLzPxPAbJK48occlTdfuh6hX2nK11Toe4D0GaMsE++SanE5
6/d49uXc/ZOrQeAk3QIDAQAB
-----END PUBLIC KEY-----`
plainText := "ExamplePwd1"
block, _ := pem.Decode([]byte(publicKeyPem))
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
cipherBytes, err := rsa.EncryptPKCS1v15(rand.Reader, pub.(*rsa.PublicKey), []byte(plainText))
if err != nil {
panic(err)
}
cipherText := strings.TrimRight(base64.URLEncoding.EncodeToString(cipherBytes), "=")
fmt.Println(cipherText)
}
const crypto = require('crypto');
const publicKeyPem = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC9kMNVuFE+2qnb1vXjlRmjKhd
HR0AEe3i/p0iQNwB082raTulbM2NNdlstG+otWweScbfxwdIj2zylVm31kdEt5yp
wOD4rzDq8MEK51R9wXLzPxPAbJK48occlTdfuh6hX2nK11Toe4D0GaMsE++SanE5
6/d49uXc/ZOrQeAk3QIDAQAB
-----END PUBLIC KEY-----`;
const plainText = 'ExamplePwd1';
const cipherBytes = crypto.publicEncrypt(
{
key: publicKeyPem,
padding: crypto.constants.RSA_PKCS1_PADDING
},
Buffer.from(plainText, 'utf8')
);
console.log(cipherBytes.toString('base64url'));
解密回推密码¶
平台回推 newPassword 时,使用您在个人中心配置的公钥加密。请用配对私钥按 PKCS#1 解密。
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
public class RsaPkcs1DecryptTest {
public static void main(String[] args) throws Exception {
String privateKeyPem = "{您的PKCS8私钥Base64}";
String cipherText = "{RSA密文}";
byte[] keyBytes = Base64.decodeBase64(privateKeyPem);
RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
String plainText = new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8");
System.out.println(plainText);
}
}
验证结果¶
- 将加密结果填入接口请求体后,不再出现
解析失败,请确认RSA公钥是否正确。 - 使用同一把私钥解密密文,应得到原始明文密码。
常见问题¶
提示解析失败,请确认 RSA 公钥是否正确¶
请确认使用的是本文中的平台公钥,填充为 PKCS#1 v1.5,而不是 OAEP。不要使用个人中心配置的那把公钥加密后调用平台接口。
密文里出现加号或斜杠导致请求失败¶
请输出 URL-Safe Base64(+ 改为 -,/ 改为 _),或对请求体做正确的 JSON 转义。
个人中心测试加密成功,但接口解密失败¶
个人中心的「测试 RSA 公钥」只验证您自己的公钥。调用平台接口仍须用平台公钥加密。