[英]Verify digital signature with public key in iOS
如何在iOS中使用公鑰驗證數字簽名而不使用任何第三方代碼(例如)打開SSL?
我需要使用公鑰驗證iOS App中的數字簽名。 有人可以幫助我在不使用第三方軟件的情況下實現這一目標。
我正在嘗試下面的代碼,但問題是我的應用程序中沒有證書,因此無法創建SecTrustRef 。
碼:
NSString *certPath = [[NSBundle mainBundle] pathForResource:@"yyy"
ofType:@"xxx"];
SecCertificateRef myCertificate = nil;
NSData *certificateData = [[NSData alloc] initWithContentsOfFile :certPath];
myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
SecTrustRef trustRef;
SecTrustCreateWithCertificates(myCertificate, myPolicy, &trustRef);
SecKeyRef keyRef = SecTrustCopyPublicKey (trustRef);
BOOL status = SecKeyRawVerify (keyRef,
kSecPaddingPKCS1SHA1,
(const uint8_t *)[data bytes],
(size_t)[data length],
(const uint8_t *)[signature bytes],
(size_t)[signature length]
);
我有以下內容:
如果我不想使用ant第三方開源,請幫助我在iOS SDK中擁有的所有選項。
您可以使用openSSL將公鑰打包到X509證書中以輕松使用iOS內置函數:
openssl req -x509 -out public_key.pem -outform pem -new -newkey rsa:2048 -keyout private_key.pem
PEM格式為base64編碼,您可以將-outform切換為DER以獲取二進制文件。 您可以通過向程序添加const NSString並使用此函數向NSData添加類別來導入PEM格式:
- (id) initWithBase64EncodedString:(NSString *) string {
NSMutableData *mutableData = nil;
if( string ) {
unsigned long ixtext = 0;
unsigned long lentext = 0;
unsigned char ch = 0;
unsigned char inbuf[4], outbuf[3]; // buffer sizes fixed by AOL LLC
short i = 0, ixinbuf = 0;
BOOL flignore = NO;
BOOL flendtext = NO;
NSData *base64Data = nil;
const unsigned char *base64Bytes = nil;
// Convert the string to ASCII data.
base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
base64Bytes = [base64Data bytes];
mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
lentext = [base64Data length];
while( YES ) {
if( ixtext >= lentext ) break;
ch = base64Bytes[ixtext++];
flignore = NO;
if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
else if( ch == '+' ) ch = 62;
else if( ch == '=' ) flendtext = YES;
else if( ch == '/' ) ch = 63;
else flignore = YES;
if( ! flignore ) {
short ctcharsinbuf = 3;
BOOL flbreak = NO;
if( flendtext ) {
if( ! ixinbuf ) break;
if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
else ctcharsinbuf = 2;
ixinbuf = 3;
flbreak = YES;
}
inbuf [ixinbuf++] = ch;
if( ixinbuf == 4 ) {
ixinbuf = 0;
outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
for( i = 0; i < ctcharsinbuf; i++ )
[mutableData appendBytes:&outbuf[i] length:1];
}
if( flbreak ) break;
}
}
}
self = [self initWithData:mutableData];
return self;
}
當你想使用現有的公鑰時,將這個文件拉入certificateData,只需將其拉出並使用openSSL以X509證書格式寫入
$ openssl rsa -in id_rsa -out pub.der -outform DER -pubout
祝好運
如果您的密鑰數據打包為PKCS12數據,請使用SecPKCS12Import導入它並使用公鑰。
您需要將數據的摘要(哈希)傳遞給驗證函數。 請參閱iOS:使用證書和簽名驗證文件 - 公鑰錯誤,驗證失敗
@interface HDSecurityPolicy :AFSecurityPolicy
@end
@implementation HDSecurityPolicy
///pem formate(base64) -> NSData
- (void)setPinnedCertificates:(NSSet *)pinnedCertificates {
[super setPinnedCertificates:pinnedCertificates];
if (self.pinnedCertificates) {
NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]];
for (NSData *pubCertificate in self.pinnedCertificates) {
id publicKey = [HDSecurityPolicy publicSecKeyFromKeyBits:pubCertificate];
if (!publicKey) {
continue;
}
[mutablePinnedPublicKeys addObject:publicKey];
}
[self setValue:mutablePinnedPublicKeys forKey:@"pinnedPublicKeys"];
}
}
// 從公鑰證書文件中獲取到公鑰的SecKeyRef指針
+ (id)publicSecKeyFromKeyBits:(NSData *)givenData {
NSMutableDictionary *options = [NSMutableDictionary dictionary];
options[(__bridge id)kSecAttrKeyType] = (__bridge id) kSecAttrKeyTypeRSA;
options[(__bridge id)kSecAttrKeyClass] = (__bridge id) kSecAttrKeyClassPublic;
NSError *error = nil;
CFErrorRef ee = (__bridge CFErrorRef)error;
////'SecKeyCreateWithData' is only available on iOS 10.0 or newer
id ret = (__bridge_transfer id)SecKeyCreateWithData((__bridge CFDataRef)givenData, (__bridge CFDictionaryRef)options, &ee);
if (error) {
return nil;
}
return ret;
}
@end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.