我花了一段时间才找到使用这些函数对数据进行签名和加密的正确方法。
我需要它来与德国健康保险提供者进行通信,作为 DiGA 的一部分。也许有人会发现它很有用。
<?php
function signAndEncrypt(string $rawData): string
{
$tempDir = __DIR__ . '/tmp';
$tempfileOriginal = tempnam($tempDir, 'original');
$tempfileSigned = tempnam($tempDir, 'signed');
$tempfileEncrypted = tempnam($tempDir, 'signedEncrypted');
file_put_contents($tempfileOriginal, $rawData);
$recipientsCertificateFile = __DIR__ . '/recipientsCertificate.pem';
$recipientsCertificate = file_get_contents($recipientsCertificateFile);
$myCertificate = file_get_contents(__DIR__ . '/my.crt');
$myPrivateKey = openssl_pkey_get_private(
file_get_contents(__DIR__ . '/my.prv.key.pem')
);
openssl_cms_sign(
input_filename: $tempfileOriginal,
output_filename: $tempfileSigned,
certificate: $myCertificate,
private_key: $myPrivateKey,
headers: [],
encoding: OPENSSL_ENCODING_DER,
);
openssl_cms_encrypt(
input_filename: $tempfileSigned,
output_filename: $tempfileEncrypted,
certificate: $recipientsCertificate,
headers: [],
flags: OPENSSL_CMS_BINARY | OPENSSL_CMS_NOSIGS | OPENSSL_CMS_NOVERIFY,
encoding: OPENSSL_ENCODING_DER,
cipher_algo: OPENSSL_CIPHER_AES_256_CBC
);
return file_get_contents($tempfileEncrypted);
}