125 lines
3.8 KiB
PHP
125 lines
3.8 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Jltx\Support\Tests\Unit;
|
||
|
|
|
||
|
|
use Jltx\Support\Security\RSA;
|
||
|
|
use RuntimeException;
|
||
|
|
|
||
|
|
beforeEach(function () {
|
||
|
|
// 生成测试用的密钥对
|
||
|
|
$this->keyPair = RSA::generateKeyPair();
|
||
|
|
$this->privateKeyContent = $this->keyPair['private_key'];
|
||
|
|
$this->publicKeyContent = $this->keyPair['public_key'];
|
||
|
|
|
||
|
|
// 格式化密钥
|
||
|
|
$this->formattedPrivateKey = RSA::privateKeyFormat($this->privateKeyContent);
|
||
|
|
$this->formattedPublicKey = RSA::publicKeyFormat($this->publicKeyContent);
|
||
|
|
|
||
|
|
// 获取密钥资源
|
||
|
|
$this->privateKey = RSA::getPrivateKey($this->formattedPrivateKey);
|
||
|
|
$this->publicKey = RSA::getPublicKey($this->formattedPublicKey);
|
||
|
|
});
|
||
|
|
|
||
|
|
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();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can format private key', function () {
|
||
|
|
$formatted = RSA::privateKeyFormat($this->privateKeyContent);
|
||
|
|
|
||
|
|
expect($formatted)->toContain('PRIVATE KEY');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can format public key', function () {
|
||
|
|
$formatted = RSA::publicKeyFormat($this->publicKeyContent);
|
||
|
|
|
||
|
|
expect($formatted)->toContain('PUBLIC KEY');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can get private key resource', function () {
|
||
|
|
$privateKey = RSA::getPrivateKey($this->formattedPrivateKey);
|
||
|
|
|
||
|
|
expect($privateKey)->toBeObject();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('can get public key resource', function () {
|
||
|
|
$publicKey = RSA::getPublicKey($this->formattedPublicKey);
|
||
|
|
|
||
|
|
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 () {
|
||
|
|
$invalidKey = "-----BEGIN PRIVATE KEY-----\ninvalidcontent\n-----END PRIVATE KEY-----";
|
||
|
|
|
||
|
|
expect(fn () => RSA::getPrivateKey($invalidKey))->toThrow(RuntimeException::class, '非法私钥');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception for invalid public key', function () {
|
||
|
|
$invalidKey = "-----BEGIN PUBLIC KEY-----\ninvalidcontent\n-----END PUBLIC KEY-----";
|
||
|
|
|
||
|
|
expect(fn () => RSA::getPublicKey($invalidKey))->toThrow(RuntimeException::class, '非法公钥');
|
||
|
|
});
|