Статус: Участник
Группы: Участники
Зарегистрирован: 24.10.2020(UTC) Сообщений: 17
|
вот весь код одной страницей. старт с - Код: (NSData*)decodeData:(NSData*)data.
Включил логи, куда смотреть? Код:static const int kGostProvType = 75;
@interface ExampleDecoder()
@property (nonatomic, assign) HCERTSTORE hMemStore;
@end
@implementation ExampleDecoder
- (NSData*)decodeData:(NSData*)data{
[self initCryptoStore];
NSDictionary *containers = [self getContainers];
NSArray *certs = [self convertCertsFromContainers:containers];
CryptoCertWrapper *rutokenCert = nil;
for (CryptoCertWrapper *cert in certs) {
if ([cert.readerName containsString:@"Aktiv Rutoken"]) {
rutokenCert = cert;
break;
}
}
if ([self importCertCtx:rutokenCert.cryptoProCert.cert toStore:self.hMemStore]){
NSError *er = nil;
NSData *decryptedData = [self privateDecryptData:data rghCertStore:self.hMemStore error:&er];
NSLog(@"decryptedData %@", decryptedData);
}
return nil;
}
- (void)initCryptoStore{
HCRYPTPROV hCryptProv = 0;
_hMemStore = CertOpenSystemStore(hCryptProv,
[@"MY" cStringUsingEncoding:NSASCIIStringEncoding]);
}
- (BOOL)importCertCtx:(PCCERT_CONTEXT)cert toStore:(HCERTSTORE) hCertStore{
DWORD dwAddDisposition = CERT_STORE_ADD_ALWAYS;
BOOL result = CertAddCertificateContextToStore(hCertStore,
cert,
dwAddDisposition,
NULL);
DWORD error = ERROR_SUCCESS;
if (!result) {
error = CSP_GetLastError();
}
return result;
}
- (NSDictionary <NSString*, NSArray*>*)getContainers{
NSMutableDictionary<NSString*, NSArray*>* result = (NSMutableDictionary<NSString*, NSArray*>*) [NSMutableDictionary new];
DWORD error = ERROR_SUCCESS;
HCRYPTPROV hCryptProv = 0;
CSP_BOOL bResult = 0;
DWORD dwLen = 0;
bResult = CryptAcquireContext(&hCryptProv, NULL, NULL, kGostProvType, CRYPT_VERIFYCONTEXT);
if (!bResult) {
error = CSP_GetLastError();
NSLog(@"CryptAcquireContext(CRYPT_VERIFYCONTEXT): %x\n", error);
}
if(0 == hCryptProv) {
NSLog(@"Invalid HCRYPTPROV");
return nil;
}
BYTE cryptFirst = CRYPT_FIRST;
for (;1;) {
CSP_SetLastError(ERROR_SUCCESS);
bResult = CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, NULL, &dwLen, cryptFirst);
error = CSP_GetLastError();
if (error == ERROR_NO_MORE_ITEMS)
break;
if (!bResult)
{
printf("CryptGetProvParam(PP_ENUMREADERS, LEN): %x\n", error);
break;
}
LPBYTE pbContainerName;
pbContainerName = (LPBYTE)malloc(dwLen);
bResult = CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, pbContainerName, &dwLen, cryptFirst);
if (bResult == 0) break;
HCRYPTPROV hContainer = 0;
if (CryptAcquireContext(&hContainer,(LPCSTR)pbContainerName, NULL, PROV_GOST_2012_256, 0)) {
BYTE pbData[1000]; // 1000 will hold the longest
DWORD cbData = 1000; // key container name.
CryptGetProvParam(hContainer, PP_FQCN, pbData, &cbData, CRYPT_FQCN);
NSString *urlStr = [NSString stringWithUTF8String:(const char *)pbData];
NSArray *components = [urlStr componentsSeparatedByString:@"\\"];
NSString *readerName = components [components.count - 2];
NSString *containerName = components [components.count - 1];
if (result[readerName] == nil) {
result[readerName] = [NSArray new];
}
NSMutableArray *ar = [result[readerName] mutableCopy];
[ar addObject:containerName];
result[readerName] = ar;
}
cryptFirst = 0;
error = CSP_GetLastError();
if (error == ERROR_NO_MORE_ITEMS)
break;
if (!bResult){
printf("CryptGetProvParam(PP_ENUMREADERS, NAME): %x\n", error);
break;
}
}
return result;
}
- (CryptoCertWrapper*)certFromContainerName:(NSString*)containerName{
HCRYPTPROV hContainer = 0;
if (CryptAcquireContext(&hContainer, (LPCSTR)containerName.UTF8String, NULL, kGostProvType, 0)) {
HCRYPTKEY key = 0;
DWORD pdwCertLen = 0;
CSP_BOOL bResult = 0;
DWORD keyType = AT_KEYEXCHANGE;
CryptGetUserKey(hContainer, keyType, &key);
CryptGetKeyParam(key, KP_CERTIFICATE, 0, &pdwCertLen, 0);
BYTE *pbDecoded = (BYTE *) malloc(pdwCertLen);
bResult = CryptGetKeyParam(key,
KP_CERTIFICATE,
pbDecoded,
&pdwCertLen,
0);
NSData *datacert = [NSData dataWithBytes:pbDecoded length:pdwCertLen];
BYTE *pbCertEncoded = (BYTE*) [datacert bytes];
DWORD cbCertEncoded = (DWORD) [datacert length];
DWORD dwCertEncodingType = X509_ASN_ENCODING |
PKCS_7_ASN_ENCODING;
PCCERT_CONTEXT cert = CertCreateCertificateContext(/*IN DWORD*/ dwCertEncodingType,
/*IN const BYTE * */ pbCertEncoded,
/*IN DWORD*/ cbCertEncoded);
DWORD rv = ERROR_SUCCESS;
DWORD cbProvName;
// LPWSTR pbProvName = NULL;
if(!CryptGetDefaultProviderW(
kGostProvType,
NULL,
CRYPT_MACHINE_DEFAULT,
NULL,
&cbProvName)){
printf("Error getting the length of the default provider name.");
rv = CSP_GetLastError();
//goto free_cert_context;
}
wchar_t pbProvName[cbProvName];
if(!CryptGetDefaultProviderW(
kGostProvType,
NULL,
CRYPT_MACHINE_DEFAULT,
pbProvName,
&cbProvName))
{
printf("Error getting the length of the default provider name.");
rv = CSP_GetLastError();
// goto free_prov_name;
}
LPWSTR wContName = NULL;
LPCSTR cName = (LPCSTR)containerName.UTF8String;
wchar_t wcstring[100];
mbstowcs (wcstring, cName, strlen(cName)+1);
CRYPT_KEY_PROV_INFO KeyProvInfo;
KeyProvInfo.pwszContainerName = wContName;
KeyProvInfo.pwszProvName = pbProvName;
KeyProvInfo.dwProvType = kGostProvType;
KeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
KeyProvInfo.dwFlags = 0;
KeyProvInfo.cProvParam = 0;
KeyProvInfo.rgProvParam = NULL;
if (!CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, (void *) &KeyProvInfo)) {
printf("CertSetCertificateContextProperty error");
rv = CSP_GetLastError();
}
CryptoCertWrapper *certObjc = [[CryptoCertWrapper alloc] init];
certObjc.cryptoProCert = [[CryptoProCertInfo alloc] initWithCert:cert
prov:hContainer
type:keyType]; // просто структура с полями
certObjc.containerName = containerName;
return certObjc;
}
return nil;
}
- (NSArray*)convertCertsFromContainers:(NSDictionary<NSString*, NSArray*>*)dictContainers{
NSMutableArray *certsResults = [@[] mutableCopy];
for (NSString *keyReader in dictContainers.allKeys) {
NSArray *containers = dictContainers[keyReader];
for (NSString *containerName in containers) {
CryptoCertWrapper *wraper = [self certFromContainerName:containerName];
wraper.readerName = keyReader;
[certsResults addObject:wraper];
}
}
return certsResults;
}
- (NSData *)privateDecryptData:(NSData *)data
rghCertStore:(HCERTSTORE)store
error:(NSError**) error {
CRYPT_DECRYPT_MESSAGE_PARA decryptPara;
decryptPara.cbSize = sizeof(PCRYPT_DECRYPT_MESSAGE_PARA);
decryptPara.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
decryptPara.cCertStore = 1;
decryptPara.rghCertStore = &store;
BYTE *pbDecrypted;
DWORD cbDecrypted = 0;
BOOL res = CryptDecryptMessage(&decryptPara,
[data bytes],
(DWORD) [data length],
NULL,
&cbDecrypted,
NULL);
if (!res) {
DWORD err = CSP_GetLastError();
NSString *errorStr = [NSString stringWithFormat: @"Cannot decrypt message: %d", err];
*error = [NSError errorWithDomain:@""
code:err
userInfo:@{NSLocalizedDescriptionKey:errorStr}];
return nil;
}
pbDecrypted = calloc(1, cbDecrypted);
res = CryptDecryptMessage(&decryptPara,
[data bytes],
(DWORD) [data length],
pbDecrypted,
&cbDecrypted,
NULL);
if (!res) {
DWORD err = CSP_GetLastError();
NSString *errorStr = [NSString stringWithFormat: @"Cannot decrypt message: %d", err];
*error = [NSError errorWithDomain:@""
code:err
userInfo:@{NSLocalizedDescriptionKey:errorStr}];
return nil;
}
NSData *decryptedData = [NSData dataWithBytes:pbDecrypted length:cbDecrypted];
free(pbDecrypted);
return decryptedData;
}
@end
Отредактировано пользователем 31 марта 2021 г. 12:44:49(UTC)
| Причина: Не указана
|