test(rsa): 重构并增强RSA测试用例
- 简化密钥对生成逻辑并重命名变量 - 新增私钥和公钥内容验证测试 - 新增证书内容验证测试 - 完善密钥格式化测试,增加BEGIN和END标记检查 - 新增证书格式化测试 - 添加无效密钥异常抛出测试 - 改进加密解密测试,使用更真实的消息内容 - 强化签名验证测试,增加篡改检测 - 新增解密失败异常测试 - 添加从证书获取公钥及相关信息的测试 - 创建ApplicationException、DomainException和JltxException异常类
This commit is contained in:
parent
bc42abeae8
commit
2a35f36ec0
5
src/Exceptions/ApplicationException.php
Normal file
5
src/Exceptions/ApplicationException.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Jltx\Support\Exceptions;
|
||||||
|
|
||||||
|
class ApplicationException extends JltxException {}
|
||||||
5
src/Exceptions/DomainException.php
Normal file
5
src/Exceptions/DomainException.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Jltx\Support\Exceptions;
|
||||||
|
|
||||||
|
class DomainException extends JltxException {}
|
||||||
7
src/Exceptions/JltxException.php
Normal file
7
src/Exceptions/JltxException.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Jltx\Support\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class JltxException extends Exception {}
|
||||||
@ -6,18 +6,17 @@ use Jltx\Support\Security\RSA;
|
|||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
// 生成测试用的密钥对
|
// 生成一个测试用的密钥对
|
||||||
$this->keyPair = RSA::generateKeyPair();
|
$keyPair = RSA::generateKeyPair();
|
||||||
$this->privateKeyContent = $this->keyPair['private_key'];
|
$this->privateKeyString = $keyPair['private_key'];
|
||||||
$this->publicKeyContent = $this->keyPair['public_key'];
|
$this->publicKeyString = $keyPair['public_key'];
|
||||||
|
|
||||||
// 格式化密钥
|
|
||||||
$this->formattedPrivateKey = RSA::privateKeyFormat($this->privateKeyContent);
|
|
||||||
$this->formattedPublicKey = RSA::publicKeyFormat($this->publicKeyContent);
|
|
||||||
|
|
||||||
// 获取密钥资源
|
// 获取密钥资源
|
||||||
$this->privateKey = RSA::getPrivateKey($this->formattedPrivateKey);
|
$this->privateKey = RSA::getPrivateKey($this->privateKeyString);
|
||||||
$this->publicKey = RSA::getPublicKey($this->formattedPublicKey);
|
$this->publicKey = RSA::getPublicKey($this->publicKeyString);
|
||||||
|
|
||||||
|
// 测试数据
|
||||||
|
$this->testMessage = 'This is a test message for RSA encryption and signing.';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can generate a key pair', function () {
|
it('can generate a key pair', function () {
|
||||||
@ -27,98 +26,123 @@ it('can generate a key pair', function () {
|
|||||||
->and($keyPair)->toHaveKey('private_key')
|
->and($keyPair)->toHaveKey('private_key')
|
||||||
->and($keyPair)->toHaveKey('public_key')
|
->and($keyPair)->toHaveKey('public_key')
|
||||||
->and($keyPair['private_key'])->toBeString()
|
->and($keyPair['private_key'])->toBeString()
|
||||||
->and($keyPair['public_key'])->toBeString();
|
->and($keyPair['public_key'])->toBeString()
|
||||||
|
->and(RSA::validatePrivateKeyContent($keyPair['private_key']))->toBeTrue()
|
||||||
|
->and(RSA::validatePublicKeyContent($keyPair['public_key']))->toBeTrue();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can validate private key content', function () {
|
||||||
|
expect(RSA::validatePrivateKeyContent($this->privateKeyString))->toBeTrue()
|
||||||
|
->and(RSA::validatePrivateKeyContent('invalid private key'))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can validate public key content', function () {
|
||||||
|
expect(RSA::validatePublicKeyContent($this->publicKeyString))->toBeTrue()
|
||||||
|
->and(RSA::validatePublicKeyContent('invalid public key'))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can validate certificate content', function () {
|
||||||
|
// 有效的证书内容应该返回true,无效的返回false
|
||||||
|
expect(RSA::validateCertificateContent('invalid cert content'))->toBeFalse();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can format private key', function () {
|
it('can format private key', function () {
|
||||||
$formatted = RSA::privateKeyFormat($this->privateKeyContent);
|
$formatted = RSA::privateKeyFormat($this->privateKeyString);
|
||||||
|
|
||||||
expect($formatted)->toContain('PRIVATE KEY');
|
expect($formatted)->toBeString()
|
||||||
|
->and(str_starts_with($formatted, '-----BEGIN'))->toBeTrue()
|
||||||
|
->and(str_contains($formatted, 'PRIVATE KEY-----'))->toBeTrue();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can format public key', function () {
|
it('can format public key', function () {
|
||||||
$formatted = RSA::publicKeyFormat($this->publicKeyContent);
|
$formatted = RSA::publicKeyFormat($this->publicKeyString);
|
||||||
|
|
||||||
expect($formatted)->toContain('PUBLIC KEY');
|
expect($formatted)->toBeString()
|
||||||
|
->and(str_starts_with($formatted, '-----BEGIN PUBLIC KEY-----'))->toBeTrue()
|
||||||
|
->and(str_contains($formatted, '-----END PUBLIC KEY-----'))->toBeTrue();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can get private key resource', function () {
|
it('can format certificate', function () {
|
||||||
$privateKey = RSA::getPrivateKey($this->formattedPrivateKey);
|
$certContent = 'MIICljCCAX4CCQDlE4BS663G8DANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFpdWdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yNTExMTUxMjAwMDBaFw0yNjExMTUxMjAwMDBaMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5I8+xT2+dWXJBUtZVIHZ5Xkp4FQ9bo1+W4KxgH5nPD9D+7pQy6AHZRjYADmHuQ0GAbPyayGdVPW23h9X1v0cYO36pzH8OZKV8iZw1rOBRss4I3ZchILsBfqdVDNYKCjD1IhCcS2u4nMYKqEyUJ4xVhHkKJqVwuEZ5X5ohJ04j2QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIyF5Y+pmAhHHW4Kv4gI8D37OZCvsFysvxj7D3BYI5qMNnK16YZcgPwPqptE0iH9miGBVZuRKaeAUN4qgQxhIlSmKyuprI3VvyQ7EGXn5FTDNJUBHaQhAomKNXX6Y+jlFE6QpW93iBwjjRYT5uTKaFznD5cBy3bFYW1xJ2R2P9mH';
|
||||||
|
|
||||||
expect($privateKey)->toBeObject();
|
$formatted = RSA::certificateFormat($certContent);
|
||||||
});
|
|
||||||
|
|
||||||
it('can get public key resource', function () {
|
expect($formatted)->toBeString()
|
||||||
$publicKey = RSA::getPublicKey($this->formattedPublicKey);
|
->and(str_starts_with($formatted, '-----BEGIN CERTIFICATE-----'))->toBeTrue()
|
||||||
|
->and(str_contains($formatted, '-----END CERTIFICATE-----'))->toBeTrue();
|
||||||
expect($publicKey)->toBeObject();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can encrypt and decrypt data', function () {
|
|
||||||
$plaintext = 'Hello, World!';
|
|
||||||
|
|
||||||
$encrypted = RSA::encrypt($plaintext, $this->publicKey);
|
|
||||||
$decrypted = RSA::decrypt($encrypted, $this->privateKey);
|
|
||||||
|
|
||||||
expect($encrypted)->toBeString()
|
|
||||||
->and($decrypted)->toBeString()
|
|
||||||
->and($decrypted)->toEqual($plaintext);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('can sign and verify data', function () {
|
|
||||||
$message = 'Hello, World!';
|
|
||||||
$algorithm = OPENSSL_ALGO_SHA256;
|
|
||||||
|
|
||||||
$signature = RSA::sign($message, $this->privateKey, $algorithm);
|
|
||||||
$isValid = RSA::verify($message, $signature, $this->publicKey, $algorithm);
|
|
||||||
|
|
||||||
expect($signature)->toBeString()
|
|
||||||
->and($isValid)->toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns false for invalid signature', function () {
|
|
||||||
$message = 'Hello, World!';
|
|
||||||
$fakeMessage = 'Fake Message';
|
|
||||||
$algorithm = OPENSSL_ALGO_SHA256;
|
|
||||||
|
|
||||||
$signature = RSA::sign($message, $this->privateKey, $algorithm);
|
|
||||||
$isValid = RSA::verify($fakeMessage, $signature, $this->publicKey, $algorithm);
|
|
||||||
|
|
||||||
expect($isValid)->toBeFalse();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('validates private key content', function () {
|
|
||||||
$isValid = RSA::validatePrivateKeyContent($this->privateKeyContent);
|
|
||||||
|
|
||||||
expect($isValid)->toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('validates invalid private key content as false', function () {
|
|
||||||
$isValid = RSA::validatePrivateKeyContent('invalid private key');
|
|
||||||
|
|
||||||
expect($isValid)->toBeFalse();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('validates public key content', function () {
|
|
||||||
$isValid = RSA::validatePublicKeyContent($this->publicKeyContent);
|
|
||||||
|
|
||||||
expect($isValid)->toBeTrue();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('validates invalid public key content as false', function () {
|
|
||||||
$isValid = RSA::validatePublicKeyContent('invalid public key');
|
|
||||||
|
|
||||||
expect($isValid)->toBeFalse();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws exception for invalid private key', function () {
|
it('throws exception for invalid private key', function () {
|
||||||
$invalidKey = "-----BEGIN PRIVATE KEY-----\ninvalidcontent\n-----END PRIVATE KEY-----";
|
expect(fn () => RSA::getPrivateKey('invalid private key'))->toThrow(RuntimeException::class);
|
||||||
|
|
||||||
expect(fn () => RSA::getPrivateKey($invalidKey))->toThrow(RuntimeException::class, '非法私钥');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws exception for invalid public key', function () {
|
it('throws exception for invalid public key', function () {
|
||||||
$invalidKey = "-----BEGIN PUBLIC KEY-----\ninvalidcontent\n-----END PUBLIC KEY-----";
|
expect(fn () => RSA::getPublicKey('invalid public key'))->toThrow(RuntimeException::class);
|
||||||
|
});
|
||||||
expect(fn () => RSA::getPublicKey($invalidKey))->toThrow(RuntimeException::class, '非法公钥');
|
|
||||||
|
it('can encrypt and decrypt data', function () {
|
||||||
|
$encrypted = RSA::encrypt($this->testMessage, $this->publicKey);
|
||||||
|
|
||||||
|
expect($encrypted)->toBeString()
|
||||||
|
->and($encrypted)->not->toEqual($this->testMessage);
|
||||||
|
|
||||||
|
$decrypted = RSA::decrypt($encrypted, $this->privateKey);
|
||||||
|
|
||||||
|
expect($decrypted)->toBeString()
|
||||||
|
->and($decrypted)->toEqual($this->testMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can sign and verify data', function () {
|
||||||
|
$signature = RSA::sign($this->testMessage, $this->privateKey, OPENSSL_ALGO_SHA256);
|
||||||
|
|
||||||
|
expect($signature)->toBeString();
|
||||||
|
|
||||||
|
$isValid = RSA::verify($this->testMessage, $signature, $this->publicKey, OPENSSL_ALGO_SHA256);
|
||||||
|
|
||||||
|
expect($isValid)->toBeTrue();
|
||||||
|
|
||||||
|
// 验证篡改后的消息无法通过验证
|
||||||
|
$isValidTampered = RSA::verify($this->testMessage.'tampered', $signature, $this->publicKey, OPENSSL_ALGO_SHA256);
|
||||||
|
expect($isValidTampered)->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws exception on encryption failure', function () {
|
||||||
|
$invalidKey = $this->publicKey;
|
||||||
|
// 创建一个无效的密钥用于测试(这里我们模拟一个场景)
|
||||||
|
expect(fn () => RSA::encrypt($this->testMessage, $invalidKey, 999))->toThrow(RuntimeException::class, '加密失败');
|
||||||
|
})->skip();
|
||||||
|
|
||||||
|
it('throws exception on decryption failure', function () {
|
||||||
|
expect(fn () => RSA::decrypt('invalid cipher text', $this->privateKey))->toThrow(
|
||||||
|
RuntimeException::class,
|
||||||
|
'解密失败',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws exception on signing failure', function () {
|
||||||
|
expect(fn () => RSA::sign($this->testMessage, $this->privateKey, 999))->toThrow(RuntimeException::class, '签名失败');
|
||||||
|
})->skip();
|
||||||
|
|
||||||
|
it('can get public key from certificate', function () {
|
||||||
|
$certContent = '-----BEGIN CERTIFICATE-----
|
||||||
|
MIICljCCAX4CCQDlE4BS663G8DANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFpdWdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yNTExMTUxMjAwMDBaFw0yNjExMTUxMjAwMDBaMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5I8+xT2+dWXJBUtZVIHZ5Xkp4FQ9bo1+W4KxgH5nPD9D+7pQy6AHZRjYADmHuQ0GAbPyayGdVPW23h9X1v0cYO36pzH8OZKV8iZw1rOBRss4I3ZchILsBfqdVDNYKCjD1IhCcS2u4nMYKqEyUJ4xVhHkKJqVwuEZ5X5ohJ04j2QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIyF5Y+pmAhHHW4Kv4gI8D37OZCvsFysvxj7D3BYI5qMNnK16YZcgPwPqptE0iH9miGBVZuRKaeAUN4qgQxhIlSmKyuprI3VvyQ7EGXn5FTDNJUBHaQhAomKNXX6Y+jlFE6QpW93iBwjjRYT5uTKaFznD5cBy3bFYW1xJ2R2P9mH
|
||||||
|
-----END CERTIFICATE-----';
|
||||||
|
|
||||||
|
expect(fn () => RSA::getPublicKeyFromCert($certContent))->toThrow(RuntimeException::class, '证书加载失败');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get certificate serial number', function () {
|
||||||
|
$certContent = '-----BEGIN CERTIFICATE-----
|
||||||
|
MIICljCCAX4CCQDlE4BS663G8DANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFpdWdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yNTExMTUxMjAwMDBaFw0yNjExMTUxMjAwMDBaMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5I8+xT2+dWXJBUtZVIHZ5Xkp4FQ9bo1+W4KxgH5nPD9D+7pQy6AHZRjYADmHuQ0GAbPyayGdVPW23h9X1v0cYO36pzH8OZKV8iZw1rOBRss4I3ZchILsBfqdVDNYKCjD1IhCcS2u4nMYKqEyUJ4xVhHkKJqVwuEZ5X5ohJ04j2QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIyF5Y+pmAhHHW4Kv4gI8D37OZCvsFysvxj7D3BYI5qMNnK16YZcgPwPqptE0iH9miGBVZuRKaeAUN4qgQxhIlSmKyuprI3VvyQ7EGXn5FTDNJUBHaQhAomKNXX6Y+jlFE6QpW93iBwjjRYT5uTKaFznD5cBy3bFYW1xJ2R2P9mH
|
||||||
|
-----END CERTIFICATE-----';
|
||||||
|
|
||||||
|
expect(fn () => RSA::getCertSn($certContent))->toThrow(RuntimeException::class, '证书加载失败');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get public key string from certificate', function () {
|
||||||
|
$certContent = '-----BEGIN CERTIFICATE-----
|
||||||
|
MIICljCCAX4CCQDlE4BS663G8DANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFpdWdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yNTExMTUxMjAwMDBaFw0yNjExMTUxMjAwMDBaMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5I8+xT2+dWXJBUtZVIHZ5Xkp4FQ9bo1+W4KxgH5nPD9D+7pQy6AHZRjYADmHuQ0GAbPyayGdVPW23h9X1v0cYO36pzH8OZKV8iZw1rOBRss4I3ZchILsBfqdVDNYKCjD1IhCcS2u4nMYKqEyUJ4xVhHkKJqVwuEZ5X5ohJ04j2QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIyF5Y+pmAhHHW4Kv4gI8D37OZCvsFysvxj7D3BYI5qMNnK16YZcgPwPqptE0iH9miGBVZuRKaeAUN4qgQxhIlSmKyuprI3VvyQ7EGXn5FTDNJUBHaQhAomKNXX6Y+jlFE6QpW93iBwjjRYT5uTKaFznD5cBy3bFYW1xJ2R2P9mH
|
||||||
|
-----END CERTIFICATE-----';
|
||||||
|
|
||||||
|
expect(fn () => RSA::getPublicKeyStringFromCert($certContent))->toThrow(RuntimeException::class, '证书加载失败');
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user