JavaPHPRSA互通密钥、签名、验签、加密、解密
RSA加密算法是⼀种⾮对称加密算法。在公开密钥加密和电⼦商业中RSA被⼴泛使⽤。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)⼀起提出的。当时他们三⼈都在⿇省理⼯学院⼯作。RSA就是他们三⼈姓⽒开头字母拼在⼀起组成的。
RSA是第⼀个⽐较完善的公开密钥算法,它既能⽤于加密,也能⽤于数字签名。这个算法经受住了多年深⼊的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有⼀定的可信性,⽬前它已经成为最流⾏的公开密钥算法。
RSA的安全基于⼤数分解的难度。其公钥和私钥是⼀对⼤素数(100到200位⼗进制数或更⼤)的函数。从⼀个公钥和密⽂恢复出明⽂的难度,等价于分解两个⼤素数之积(这是公认的数学难题)。
RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表:
版本
语⾔版本
PHP7.3.11
Java  1.8.0_231
密钥⽣成
PHP
RSAUtils::resetGenKeyPair
public static function resetGenKeyPair()
{
$config = array(
"private_key_bits" => self::PRIVATE_KEY_BITS,
"private_key_type" => self::KEY_ALGORITHM,
);
$openssl = openssl_pkey_new($config);
openssl_pkey_export($openssl, $privateKey);
$publicKey = openssl_pkey_get_details($openssl);
$publicKey = $publicKey["key"];
return [
'publicKey'    => $publicKey,
'privateKey'    => $privateKey,
'publicKeyStr'  => self::key2str($publicKey),
'privateKeyStr' => self::key2str($privateKey)
];
}
Java
static Map<String, Object> resetGenKeyPair() throws Exception {
KeyPairGenerator keyPairGen = Instance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair            = ateKeyPair();
RSAPublicKey publicKey    = (RSAPublicKey) Public();
RSAPrivateKey privateKey  = (RSAPrivateKey) Private();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
签名
私钥加签。
有时签名可能会因为数据编码不同⽽导致不⼀致,所以要求 PHP 和 Java 都对数据进⾏编码处理。
PHP
RSAUtils::sign
public static function sign($dataStr, $privateKey)
{
$dataStr = self::str2utf8($dataStr);
$privateKeyId = openssl_get_privatekey($privateKey);
openssl_sign($dataStr, $sign, $privateKeyId, self::SIGNATURE_ALGORITHM);
openssl_free_key($privateKeyId);
return base64_encode($sign);
}
Java
RSAUtils.sign
static String sign(String data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
PrivateKey privateK  = atePrivate(pkcs8KeySpec);
Signature signature  = Instance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.Bytes(ENCODING));
deToString(signature.sign());
}
验签
公钥验签。
PHP
RSAUtils::verifySign
public static function verifySign($dataStr, $publicKey, $sign)
{
$dataStr    = self::str2utf8($dataStr);
$publicKeyId = openssl_get_publickey($publicKey);
return (boolean) openssl_verify($dataStr, base64_decode($sign), $publicKeyId, self::SIGNATURE_ALGORITHM);
}
Java
RSAUtils.verifySign
static boolean verifySign(String data, String publicKey, String sign) throws Exception {
try {
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory      = Instance(KEY_ALGORITHM);
PublicKey publicK          = atePublic(keySpec);
Signature signature        = Instance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.Bytes(ENCODING));
return signature.verify(Base64.decode(sign));
} catch (Exception e) {
throw e;
}
}
加密
公钥加密
PHP
RSAUtils::encryptByPublicKey
public static function encryptByPublicKey($dataStr, $publicKey)
{
$dataStr    = self::str2utf8($dataStr);
$publicKeyId = openssl_get_publickey($publicKey);
$data        = "";
$dataArray = str_split($dataStr, self::PRIVATE_KEY_BITS / 8 - 11);
foreach ($dataArray as $value) {
openssl_public_encrypt($value,$encryptedTemp, $publicKeyId,self::EN_DE_ALGORITHM);
$data .= $encryptedTemp;
}
openssl_free_key($publicKeyId);
return base64_encode($data);
}
Java
static String encryptByPublicKey(String dataStr, String publicKey) throws Exception {
byte[] data    = Bytes(ENCODING);
byte[] keyBytes = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key publicK          = atePublic(x509KeySpec);
Cipher cipher        = Algorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
java源代码加密out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = ByteArray();
out.close();
deToString(encryptedData);
}
私钥加密
PHP
RSAUtils::encryptByPrivateKey
public static function encryptByPrivateKey($dataStr, $privateKey)
{
$dataStr      = self::str2utf8($dataStr);
$privateKeyId = openssl_get_privatekey($privateKey);
$data        = "";
$dataArray = str_split($dataStr, self::PRIVATE_KEY_BITS / 8 - 11);
foreach ($dataArray as $value) {
openssl_private_encrypt($value,$encryptedTemp, $privateKeyId,self::EN_DE_ALGORITHM);
$data .= $encryptedTemp;
}
openssl_free_key($privateKeyId);
return base64_encode($data);
}
Java
static String encryptByPrivateKey(String dataStr, String privateKey) throws Exception {
byte[] data    = Bytes(ENCODING);
byte[] keyBytes = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key privateK          = atePrivate(pkcs8KeySpec);
Cipher cipher        = Algorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = ByteArray();
out.close();
deToString(encryptedData);
}
解密
公钥解密
PHP
RSAUtils::decryptByPublicKey
public static function decryptByPublicKey($encryptData, $publicKey) {
$decrypted  = "";
$decodeStr  = base64_decode($encryptData);
$publicKeyId = openssl_get_publickey($publicKey);
$enArray = str_split($decodeStr, self::PRIVATE_KEY_BITS / 8);
foreach ($enArray as $value) {
openssl_public_decrypt($value,$decryptedTemp, $publicKeyId,self::EN_DE_ALGORITHM);
$decrypted .= $decryptedTemp;
}
openssl_free_key($publicKeyId);
return $decrypted;
}
Java
RSAUtils.decryptByPublicKey
static String decryptByPublicKey(String encryptedDataStr, String publicKey) throws Exception {    byte[] encryptedData = Base64.decode(encryptedDataStr);
byte[] keyBytes      = Base64.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key publicK = atePublic(x509KeySpec);
Cipher cipher = Algorithm());
cipher.init(Cipher.DECRYPT_MODE, publicK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = ByteArray();
out.close();
return new String(decryptedData, ENCODING);
}
私钥解密
PHP
RSAUtils::decryptByPrivateKey
public static function decryptByPrivateKey($encryptData, $private) {
$decrypted    = "";
$decodeStr    = base64_decode($encryptData);
$privateKeyId = openssl_get_privatekey($private);
$enArray = str_split($decodeStr, self::PRIVATE_KEY_BITS / 8);
foreach ($enArray as $value) {
openssl_private_decrypt($value,$decryptedTemp, $privateKeyId,self::EN_DE_ALGORITHM);
$decrypted .= $decryptedTemp;
}
openssl_free_key($privateKeyId);
return $decrypted;
}
Java
RSAUtils.decryptByPrivateKey
static String decryptByPrivateKey(String encryptedDataStr, String privateKey) throws Exception {    byte[] encryptedData = Base64.decode(encryptedDataStr);
byte[] keyBytes      = Base64.decode(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = Instance(KEY_ALGORITHM);
Key privateK          = atePrivate(pkcs8KeySpec);
Cipher cipher        = Algorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = ByteArray();
out.close();
return new String(decryptedData, ENCODING);
}
Demo
完整 Demo 源码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。