mirror of
				https://github.com/crypto-pro-web/crypto-pro-php.git
				synced 2025-10-30 01:43:23 +03:00 
			
		
		
		
	Проверка подписей
This commit is contained in:
		
							parent
							
								
									18a156a586
								
							
						
					
					
						commit
						e077c60c2b
					
				
							
								
								
									
										17
									
								
								src/Constants/CAPICOM_ENCODE.php
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								src/Constants/CAPICOM_ENCODE.php
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  | 
 | ||||||
|  | namespace Webmasterskaya\CryptoPro\Constants; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Тип перечисления CAPICOM_ENCODING_TYPE указывает используемый тип кодирования. | ||||||
|  |  * | ||||||
|  |  * @link https://learn.microsoft.com/windows/win32/seccrypto/capicom-encoding-type?redirectedfrom=MSDN | ||||||
|  |  */ | ||||||
|  | class CAPICOM_ENCODE | ||||||
|  | { | ||||||
|  | 	const ANY = 0xffffffff; // Данные сохраняются в виде строки в кодировке Base64 или чистой двоичной последовательности. Этот тип кодирования используется только для входных данных с неизвестным типом кодирования. Представлен в CAPICOM 2.0.
 | ||||||
|  | 
 | ||||||
|  | 	const BASE64 = 0; // Данные сохраняются в виде строки в кодировке Base64.
 | ||||||
|  | 
 | ||||||
|  | 	const BINARY = 1; // Данные сохраняются в виде чистой двоичной последовательности.
 | ||||||
|  | } | ||||||
| @ -3,6 +3,7 @@ | |||||||
| namespace Webmasterskaya\CryptoPro; | namespace Webmasterskaya\CryptoPro; | ||||||
| 
 | 
 | ||||||
| use Webmasterskaya\CryptoPro\Constants\CAPICOM_CERTIFICATE_FIND_TYPE; | use Webmasterskaya\CryptoPro\Constants\CAPICOM_CERTIFICATE_FIND_TYPE; | ||||||
|  | use Webmasterskaya\CryptoPro\Constants\CAPICOM_ENCODE; | ||||||
| use Webmasterskaya\CryptoPro\Constants\CAPICOM_PROPID; | use Webmasterskaya\CryptoPro\Constants\CAPICOM_PROPID; | ||||||
| use Webmasterskaya\CryptoPro\Helpers\CertificateHelper; | use Webmasterskaya\CryptoPro\Helpers\CertificateHelper; | ||||||
| use Webmasterskaya\CryptoPro\Helpers\ErrorMessageHelper; | use Webmasterskaya\CryptoPro\Helpers\ErrorMessageHelper; | ||||||
| @ -258,7 +259,6 @@ class CryptoPro | |||||||
| 
 | 
 | ||||||
| 			$cadesSigner->set_Certificate($cadesCertificate); | 			$cadesSigner->set_Certificate($cadesCertificate); | ||||||
| 
 | 
 | ||||||
| 			/** @var \CPAttributes $cadesAuthAttrs */ |  | ||||||
| 			$cadesAuthAttrs = $cadesSigner->get_AuthenticatedAttributes(); | 			$cadesAuthAttrs = $cadesSigner->get_AuthenticatedAttributes(); | ||||||
| 			$cadesAuthAttrs->Add($cadesAttrs); | 			$cadesAuthAttrs->Add($cadesAttrs); | ||||||
| 
 | 
 | ||||||
| @ -266,7 +266,6 @@ class CryptoPro | |||||||
| 			$cadesSignedData->set_Content($messageBase64); | 			$cadesSignedData->set_Content($messageBase64); | ||||||
| 
 | 
 | ||||||
| 			$cadesSigner->set_Options(CERTIFICATE_INCLUDE_WHOLE_CHAIN); | 			$cadesSigner->set_Options(CERTIFICATE_INCLUDE_WHOLE_CHAIN); | ||||||
| 
 |  | ||||||
| 		} | 		} | ||||||
| 		catch (\Throwable $e) | 		catch (\Throwable $e) | ||||||
| 		{ | 		{ | ||||||
| @ -280,7 +279,7 @@ class CryptoPro | |||||||
| 				$cadesSigner, | 				$cadesSigner, | ||||||
| 				PKCS7_TYPE, | 				PKCS7_TYPE, | ||||||
| 				false, | 				false, | ||||||
| 				ENCODE_BASE64 | 				CAPICOM_ENCODE::BASE64 | ||||||
| 			); | 			); | ||||||
| 		} | 		} | ||||||
| 		catch (\Throwable $e) | 		catch (\Throwable $e) | ||||||
| @ -367,7 +366,13 @@ class CryptoPro | |||||||
| 
 | 
 | ||||||
| 		try | 		try | ||||||
| 		{ | 		{ | ||||||
| 			$signature = $cadesSignedData->SignHash($cadesHashedData, $cadesSigner, PKCS7_TYPE); | 			/** @var string $signature */ | ||||||
|  | 			$signature = $cadesSignedData->SignHash( | ||||||
|  | 				$cadesHashedData, | ||||||
|  | 				$cadesSigner, | ||||||
|  | 				PKCS7_TYPE, | ||||||
|  | 				CAPICOM_ENCODE::BASE64 | ||||||
|  | 			); | ||||||
| 		} | 		} | ||||||
| 		catch (\Throwable $e) | 		catch (\Throwable $e) | ||||||
| 		{ | 		{ | ||||||
| @ -844,4 +849,176 @@ class CryptoPro | |||||||
| 
 | 
 | ||||||
| 		return $cadesCertificate; | 		return $cadesCertificate; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Проверяет присоеденённую подпись и возвращает информацию о подписантах | ||||||
|  | 	 * | ||||||
|  | 	 * @param   string  $signedMessage  подписанное сообщение | ||||||
|  | 	 * | ||||||
|  | 	 * @throws \Exception | ||||||
|  | 	 * @return array Информация о подписантах | ||||||
|  | 	 */ | ||||||
|  | 	public static function verifyAttachedSignature(string $signedMessage) | ||||||
|  | 	{ | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSignedData = new \CPSignedData(); | ||||||
|  | 			$cadesSignedData->set_Content($signedMessage); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при инициализации проверки подписи')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSignedData->VerifyCades($signedMessage, CADES_BES, false); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при проверке подписи')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSigners      = $cadesSignedData->get_Signers(); | ||||||
|  | 			$cadesSignersCount = (int) $cadesSigners->get_Count(); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка получения списка подписантов')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!$cadesSignersCount) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception('Нет доступных подписантов'); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		$signers = []; | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			while ($cadesSignersCount) | ||||||
|  | 			{ | ||||||
|  | 				$cadesSigner      = $cadesSigners->get_Item($cadesSignersCount); | ||||||
|  | 				$cadesCertificate = $cadesSigner->get_Certificate(); | ||||||
|  | 				$certificate      = new Certificate( | ||||||
|  | 					$cadesCertificate, | ||||||
|  | 					CertificateHelper::extractCommonName($cadesCertificate->get_SubjectName()), | ||||||
|  | 					$cadesCertificate->get_IssuerName(), | ||||||
|  | 					$cadesCertificate->get_SubjectName(), | ||||||
|  | 					$cadesCertificate->get_Thumbprint(), | ||||||
|  | 					$cadesCertificate->get_ValidFromDate(), | ||||||
|  | 					$cadesCertificate->get_ValidToDate() | ||||||
|  | 				); | ||||||
|  | 
 | ||||||
|  | 				$signers[] = [ | ||||||
|  | 					'signing_time' => $cadesSigner->get_SigningTime(), | ||||||
|  | 					'certificate'  => $certificate | ||||||
|  | 				]; | ||||||
|  | 
 | ||||||
|  | 				$cadesSignersCount--; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при чтении информации о подписанте')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return $signers; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Проверяет отсоеденённую подпись по значению хэш-функции и возвращает информацию о подписантах | ||||||
|  | 	 * | ||||||
|  | 	 * @param   string  $signedMessage  подписанное сообщение | ||||||
|  | 	 * @param   string  $messageHash    хеш подписываемого сообщения, сгенерированный по ГОСТ Р 34.11-2012 256 бит | ||||||
|  | 	 * | ||||||
|  | 	 * @throws \Exception | ||||||
|  | 	 * @return array Информация о подписантах | ||||||
|  | 	 */ | ||||||
|  | 	public static function verifyDetachedSignature(string $signedMessage, string $messageHash) | ||||||
|  | 	{ | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSignedData = new \CPSignedData(); | ||||||
|  | 			$cadesHashedData = new \CPHashedData(); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при инициализации проверки подписи')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesHashedData->set_Algorithm(CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256); | ||||||
|  | 			$cadesHashedData->SetHashValue($messageHash); | ||||||
|  | 
 | ||||||
|  | 			// Для получения объекта отсоединенной (открепленной) подписи, необходимо задать любой контент.
 | ||||||
|  | 			// Этот баг описан на форуме.
 | ||||||
|  | 			// https://www.cryptopro.ru/forum2/default.aspx?g=posts&m=78553#post78553
 | ||||||
|  | 			$cadesSignedData->set_Content(123); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при установке хеша')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSignedData->VerifyHash($cadesHashedData, $signedMessage, PKCS7_TYPE); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при проверке подписи')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			$cadesSigners      = $cadesSignedData->get_Signers(); | ||||||
|  | 			$cadesSignersCount = (int) $cadesSigners->get_Count(); | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка получения списка подписантов')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!$cadesSignersCount) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception('Нет доступных подписантов'); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		$signers = []; | ||||||
|  | 
 | ||||||
|  | 		try | ||||||
|  | 		{ | ||||||
|  | 			while ($cadesSignersCount) | ||||||
|  | 			{ | ||||||
|  | 				$cadesSigner      = $cadesSigners->get_Item($cadesSignersCount); | ||||||
|  | 				$cadesCertificate = $cadesSigner->get_Certificate(); | ||||||
|  | 				$certificate      = new Certificate( | ||||||
|  | 					$cadesCertificate, | ||||||
|  | 					CertificateHelper::extractCommonName($cadesCertificate->get_SubjectName()), | ||||||
|  | 					$cadesCertificate->get_IssuerName(), | ||||||
|  | 					$cadesCertificate->get_SubjectName(), | ||||||
|  | 					$cadesCertificate->get_Thumbprint(), | ||||||
|  | 					$cadesCertificate->get_ValidFromDate(), | ||||||
|  | 					$cadesCertificate->get_ValidToDate() | ||||||
|  | 				); | ||||||
|  | 
 | ||||||
|  | 				$signers[] = [ | ||||||
|  | 					'signing_time' => $cadesSigner->get_SigningTime(), | ||||||
|  | 					'certificate'  => $certificate | ||||||
|  | 				]; | ||||||
|  | 
 | ||||||
|  | 				$cadesSignersCount--; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		catch (\Throwable $e) | ||||||
|  | 		{ | ||||||
|  | 			throw new \Exception(ErrorMessageHelper::getErrorMessage($e, 'Ошибка при чтении информации о подписанте')); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return $signers; | ||||||
|  | 	} | ||||||
| } | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user