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, '证书加载失败'); });