support/tests/Unit/RsaTest.php

149 lines
8.5 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Jltx\Support\Tests\Unit;
use Jltx\Support\Security\RSA;
use RuntimeException;
beforeEach(function () {
// 生成一个测试用的密钥对
$keyPair = RSA::generateKeyPair();
$this->privateKeyString = $keyPair['private_key'];
$this->publicKeyString = $keyPair['public_key'];
// 获取密钥资源
$this->privateKey = RSA::getPrivateKey($this->privateKeyString);
$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 () {
$keyPair = RSA::generateKeyPair();
expect($keyPair)->toBeArray()
->and($keyPair)->toHaveKey('private_key')
->and($keyPair)->toHaveKey('public_key')
->and($keyPair['private_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 () {
$formatted = RSA::privateKeyFormat($this->privateKeyString);
expect($formatted)->toBeString()
->and(str_starts_with($formatted, '-----BEGIN'))->toBeTrue()
->and(str_contains($formatted, 'PRIVATE KEY-----'))->toBeTrue();
});
it('can format public key', function () {
$formatted = RSA::publicKeyFormat($this->publicKeyString);
expect($formatted)->toBeString()
->and(str_starts_with($formatted, '-----BEGIN PUBLIC KEY-----'))->toBeTrue()
->and(str_contains($formatted, '-----END PUBLIC KEY-----'))->toBeTrue();
});
it('can format certificate', function () {
$certContent = 'MIICljCCAX4CCQDlE4BS663G8DANBgkqhkiG9w0BAQUFADCBjTELMAkGA1UEBhMCVVMxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFpdWdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTAeFw0yNTExMTUxMjAwMDBaFw0yNjExMTUxMjAwMDBaMIGNMQswCQYDVQQGEwJVUzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC5I8+xT2+dWXJBUtZVIHZ5Xkp4FQ9bo1+W4KxgH5nPD9D+7pQy6AHZRjYADmHuQ0GAbPyayGdVPW23h9X1v0cYO36pzH8OZKV8iZw1rOBRss4I3ZchILsBfqdVDNYKCjD1IhCcS2u4nMYKqEyUJ4xVhHkKJqVwuEZ5X5ohJ04j2QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIyF5Y+pmAhHHW4Kv4gI8D37OZCvsFysvxj7D3BYI5qMNnK16YZcgPwPqptE0iH9miGBVZuRKaeAUN4qgQxhIlSmKyuprI3VvyQ7EGXn5FTDNJUBHaQhAomKNXX6Y+jlFE6QpW93iBwjjRYT5uTKaFznD5cBy3bFYW1xJ2R2P9mH';
$formatted = RSA::certificateFormat($certContent);
expect($formatted)->toBeString()
->and(str_starts_with($formatted, '-----BEGIN CERTIFICATE-----'))->toBeTrue()
->and(str_contains($formatted, '-----END CERTIFICATE-----'))->toBeTrue();
});
it('throws exception for invalid private key', function () {
expect(fn () => RSA::getPrivateKey('invalid private key'))->toThrow(RuntimeException::class);
});
it('throws exception for invalid public key', function () {
expect(fn () => RSA::getPublicKey('invalid public key'))->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, '证书加载失败');
});