최근에는 여러 인터페이스를 타사 시스템과 연결해야 하는데 상대방에서 게시물 데이터에 RSA 암호화가 필요하다고 해서 Baidu에서 PHP RSA 암호화 처리에 대해 검색했는데 그럴 수도 있습니다. 다음 예가 발견되었습니다.
/** * @uses 公钥加密 * @param string $data * @return null|string */ public function publicEncrypt($data = '') { if (!is_string($data)) { return null; } return openssl_public_encrypt($data, $encrypted, $this->_getPublicKey()) ? base64_encode($encrypted) : null; }
그래서 저는 그것을 제 프로젝트에 복사하고 테스트하기 전에 약간 수정했습니다.
<?php $string = '基督教解决基督教解决决'; $ret = publicEncrypt($string); var_dump($ret); /** * @uses 公钥加密 * @param string $data * @return null|string */ function publicEncrypt($data = '') { $publicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiX1bIq02AFypLOJ4byShfo6+D6pj0rQrdAtZ8Bb2Z4YwdCZS5vlEduBiVCZSKfF70M0nk4gMqhAKcgwqWxgI1/j8OrX401AssfaiXr2JqsAl679s+Xlwe0jppNe1832+3g0YOawDTpAQsUJDu1DpnyGnUz0qeac0/GiAJlXzKUP+/3db8haDuOkgYrT8A6twGAm7YwIuliieDWDcUS/CQzXGRtwtZQqUJDQsWC1lCML1kRUjbZ2EM2EzyttgHN0SsNryhVLHXSFXpDWbeqQwk36axojGF1lbg/oVQy+BnYJx8pKpTgSwIDAQAB'; $publicKey = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($publicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; if (!is_string($data)) { return null; } return openssl_public_encrypt($data, $encrypted, $publicKey) ? base64_encode($encrypted) : null; }
프로그램이 인쇄합니다:
string(344) "HSqVQbyhmWYrptvgzK+ggqmma88QRFVJerXTrZ+RpYqhZr/Dr9au9wxX+aAYy1wRh0eBk+fIpU4wkEZs6P5yozf5e/rAAEYUOImTJZcOvZqr89znT3yqaV8ME+vR16FLK5sk3BwgpOWI6X+wBwU2cLnHKDdj9RpYWAYhi/mn8XJj4/srKZbSgAjvzWqZI9gfqiJNdz8kf/MPtQ65cSlAhvh4eByY8cLGfgUXV0dxzWAkwTSPl2faSq3GHsNMXnxwoNjIvqz/IuZavqABNVZCwrZC3ZVb+Op7wF9GxrkIdJYzmHpX/wNn1DPLHUvghtO/WmfN4Jb2ZVzTsneB5B3Z6g=="
모든 것이 보입니다. 정상인데, 실제 프로젝트에서 상대적으로 긴 json 문자열을 암호화할 때 null이 반환되는 것을 발견했는데, 이때 openssl_public_encrypt 함수가 false를 반환하여 암호화에 실패했음을 알 수 있었습니다. 길이가 다른 문자열을 전달하고 여러 번 테스트한 결과 문자열 길이가 100자를 초과하면 암호화가 실패한다는 것을 발견했습니다. 상대방
/** * 用公钥加密 * @param data * @param publicKey * @return * @throws Exception */ public static String rsaEncrypt(String data, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); int inputLen = data.getBytes().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.getBytes(), offset, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); // 加密后的字符串 return Base64.getEncoder().encodeToString(encryptedData); }
에서 보낸 Java 암호화 예시를 살펴보니 문자열에 대해 분할 작업을 수행하여 다음과 같은 수정 버전이 생성되었습니다.
/** * 公钥加密 * @param string $data * @return null|string */ public function publicEncrypt($data = '') { if (!is_string($data)) { return null; } $dataLength = mb_strlen($data); $offet = 0; $length = 128; $i = 0; $string = ''; while ($dataLength - $offet > 0) { if ($dataLength - $offet > $length) { $str = mb_substr($data, $offet, $length); } else { $str = mb_substr($data, $offet, $dataLength - $offet); } $encrypted = ''; openssl_public_encrypt($str,$encrypted, $this->rsaPublicKey, OPENSSL_PKCS1_OAEP_PADDING);//这个OPENSSL_PKCS1_OAEP_PADDING是对方要求要用这种padding方式 $string .= $encrypted; $i ++; $offet = $i * $length; } return base64_encode($string); }
현재 테스트에서는 암호화 실패 문제가 발견되지 않았습니다. ~ 문제 해결
권장: "PHP Video Tutorial"
위 내용은 기록: PHP rsa 암호화 처리 실패에 대한 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!