簡體   English   中英

使用.pem格式的公鑰在Xcode中進行簽名驗證

[英]Signature verification in Xcode using public key in .pem format

我需要使用公鑰在Xcode中驗證數字簽名的數據(用私鑰在PHP中簽名)。 我在命令行中的iOS中生成了密鑰對,兩個密鑰均為.pem格式。 我遵循示例以進行生成並隨后在Xcode中驗證數據。 但是,我一直無法以SecKeyRef格式從密鑰鏈中存儲和獲取公鑰。 問題是我不斷從stripPublicKeyHeader函數獲取NSData對象== NULL,因此我的程序在行上崩潰:[peerPublicKeyAttr setObject:publicKeyData forKey:(id)CFBridgingRelease(kSecValueData)]; 在addPeerPublicKey函數中。 您能否檢查代碼的穩定性並幫助確定問題,還是有人可以使用.pem文件中的公鑰驗證簽名數據的有效解決方案?

提前非常感謝您。

#include <CoreFoundation/CoreFoundation.h>
#import "NSData+Base64.h"
#import "ViewController.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
#include <Security/Security.h>

-(void)VerifyMyData{

NSString* path = [[NSBundle mainBundle] pathForResource:@"MY_Public_Key" ofType:@"pem"];
NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];  //retrieve public key content, this is OK
NSString *publicKey;
NSString *startPublicKey = @"-----BEGIN PUBLIC KEY-----";
NSString *endPublicKey = @"-----END PUBLIC KEY-----";
NSScanner *scanner = [NSScanner scannerWithString:content];
[scanner scanUpToString:startPublicKey intoString:nil];
[scanner scanString:startPublicKey intoString:nil];
[scanner scanUpToString:endPublicKey intoString:&publicKey];

 //remoteLog is our function to log our logs
[ViewController remoteLog:[NSString stringWithFormat:@"Public key path:%@",path] withlevel:SPECIAL_LOG];
[ViewController remoteLog:[NSString stringWithFormat:@"Public key content:%@",content] withlevel:SPECIAL_LOG];
[ViewController remoteLog:[NSString stringWithFormat:@"content of public key without tags: %@",publicKey] withlevel:SPECIAL_LOG];

NSData *d_key = [NSData dataFromBase64String:content];
NSData *strippedKey =  [ViewController stripPublicKeyHeader:d_key];
NSString *StringtoDecode = [[NSBundle mainBundle]objectForInfoDictionaryKey:@"expirySetYear"];

 if (d_key == NULL) {
    [ViewController remoteLog:@"No data in d_key" withlevel:SPECIAL_LOG];
 }
 if (strippedKey == NULL) {
    [ViewController remoteLog:@"No data in strippedKey" withlevel:SPECIAL_LOG];
 } 
 //in this function it crashes because of strippedKey ==NULL
 [ViewController addPeerPublicKey:@"MIA_KEY" keyBits:strippedKey]; 
}


+ (NSData *)stripPublicKeyHeader:(NSData *)d_key
{
// Skip ASN.1 public key header
if (d_key == nil) {
    [ViewController remoteLog:@"stripPublicKeyHeader: d_key == nil" withlevel:SPECIAL_LOG];
    return(nil);
}

unsigned int len = [d_key length];
if (!len) {
    [ViewController remoteLog:@"stripPublicKeyHeader: length of d_key == nil" withlevel:SPECIAL_LOG];
    return(nil);
}

unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int  idx    = 0;

if (c_key[idx++] != 0x30) {
    [ViewController remoteLog:@"stripPublicKeyHeader: section 0" withlevel:SPECIAL_LOG];
    return(nil);
}

if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;

// PKCS #1 rsaEncryption szOID_RSA_RSA
static unsigned char seqiod[] =
{ 0x30,   0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
    0x01, 0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod, 15)) {
    [ViewController remoteLog:@"stripPublicKeyHeader: section 1" withlevel:SPECIAL_LOG];
    return(nil);
}

idx += 15;

if (c_key[idx++] != 0x03) {
    [ViewController remoteLog:@"stripPublicKeyHeader: section 2" withlevel:SPECIAL_LOG];
    return(nil);
}

if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;

if (c_key[idx++] != '\0') {
    [ViewController remoteLog:@"stripPublicKeyHeader: section 3" withlevel:SPECIAL_LOG];
    return(nil);
}

  // Now make a new NSData from this buffer   *****THIS IS PROBABLY PROBLEM*****
  return([NSData dataWithBytes:&c_key[idx] length:len - idx]);
}

+ (void)addPeerPublicKey:(NSString *)peerName keyBits:(NSData *)publicKeyData {

OSStatus sanityCheck = noErr;
CFTypeRef persistPeer = NULL;
//[self removePeerPublicKey:peerName];

NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];

[peerPublicKeyAttr setObject:(id)CFBridgingRelease(kSecClassKey) forKey:(id)CFBridgingRelease(kSecClass)];
[peerPublicKeyAttr setObject:(id)CFBridgingRelease(kSecAttrKeyTypeRSA) forKey:(id)CFBridgingRelease(kSecAttrKeyType)];
[peerPublicKeyAttr setObject:peerTag forKey:(id)CFBridgingRelease(kSecAttrApplicationTag)];
[peerPublicKeyAttr setObject:publicKeyData forKey:(id)CFBridgingRelease(kSecValueData)];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)CFBridgingRelease(kSecReturnData)];
sanityCheck = SecItemAdd((CFDictionaryRef) CFBridgingRetain(peerPublicKeyAttr), (CFTypeRef *)&persistPeer);


if(sanityCheck == errSecDuplicateItem){
    //TRC_DBG(@"Problem adding the peer public key to the keychain, OSStatus == %ld.", sanityCheck );
}

//TRC_DBG(@"SecItemAdd OSStATUS = %ld", sanityCheck);

//        TRC_DBG(@"PersistPeer privatekey data after import into keychain %@", persistPeer);
persistPeer = NULL;
[peerPublicKeyAttr removeObjectForKey:(id)CFBridgingRelease(kSecValueData)];
sanityCheck = SecItemCopyMatching((CFDictionaryRef) CFBridgingRetain(peerPublicKeyAttr), (CFTypeRef*)&persistPeer);

//TRC_DBG(@"SecItemCopying OSStATUS = %ld", sanityCheck);
//        TRC_DBG(@"SecItem copy matching returned this public key data %@", persistPeer);
// The nice thing about persistent references is that you can write their value out to disk and
// then use them later. I don't do that here but it certainly can make sense for other situations
// where you don't want to have to keep building up dictionaries of attributes to get a reference.
//
// Also take a look at SecKeyWrapper's methods (CFTypeRef)getPersistentKeyRefWithKeyRef:(SecKeyRef)key
// & (SecKeyRef)getKeyRefWithPersistentKeyRef:(CFTypeRef)persistentRef.
//[peerTag release];
//[peerPublicKeyAttr release];
if (persistPeer) CFRelease(persistPeer);
}

看來您應該使用Base64解碼publicKey ,而不是content 那可以解釋為什么在stripPublicKeyHeader得到NULLstripPublicKeyHeader

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM