//这是.h文件里的 不过我主要用到了前两个方法 因为我们返回的需要用的就是 return base64 encoded string
#import <Foundation/Foundation.h>
#define pubkey @"-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCl2JMbsgVrx//0co2ypLZ/aOVnt7Wcd/FZ4M2mE5FKAuvQnBaDmmOlT5ywGQ+xy2M2oNnoZXtUmAvR+0n5M2xZRlL5Y8ZRpH4sKQC5JWOBgFqxSvrrefJhvLP7zoMSD3SDQSxFoc7CGYIshfrKri+d8/LxTyDX1AQAB-----END PUBLIC KEY-----"
@interface RSA : NSObject
// return base64 encoded string
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey;
// return raw data
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey;
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey;
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey;
@end
#import "RSAb.h"
#import <Security/Security.h>
@implementation RSA
/*
static NSString *base64_encode(NSString *str){
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
if(!data){
return nil;
}
return base64_encode_data(data);
}
*/
static NSString *base64_encode_data(NSData *data){
data = [data base64EncodedDataWithOptions:0];
NSString *ret = [[NSStringalloc] initWithData:dataencoding:NSUTF8StringEncoding];
return ret;
}
static NSData *base64_decode(NSString *str){
NSData *data = [[NSDataalloc] initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];
return data;
}
+ (NSData *)stripPublicKeyHeader:(NSData *)d_key{
// Skip ASN.1 public key header
if (d_key ==nil) return(nil);
unsignedlong len = [d_key length];
if (!len)return(nil);
unsignedchar *c_key = (unsignedchar *)[d_key bytes];
unsignedint idx= 0;
if (c_key[idx++] !=0x30) return(nil);
if (c_key[idx] >0x80) idx += c_key[idx] -0x80 + 1;
else idx++;
// PKCS #1 rsaEncryption szOID_RSA_RSA
staticunsigned char seqiod[] =
{ 0x30, 0x0d, 0x06,0x09, 0x2a,0x86, 0x48,0x86, 0xf7,0x0d, 0x01,0x01,
0x01,0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod,15)) return(nil);
idx += 15;
if (c_key[idx++] !=0x03) return(nil);
if (c_key[idx] >0x80) idx += c_key[idx] -0x80 + 1;
else idx++;
if (c_key[idx++] !='\0') return(nil);
// Now make a new NSData from this buffer
return([NSDatadataWithBytes:&c_key[idx]length:len - idx]);
}
+ (NSData *)stripPrivateKeyHeader:(NSData *)d_key{
// Skip ASN.1 private key header
if (d_key ==nil) return(nil);
unsignedlong len = [d_key length];
if (!len)return(nil);
unsignedchar *c_key = (unsignedchar *)[d_key bytes];
unsignedint idx= 22;//magic byte at offset 22
if (0x04 != c_key[idx++])return nil;
//calculate length of the key
unsignedint c_len = c_key[idx++];
int det = c_len &0x80;
if (!det) {
c_len = c_len & 0x7f;
} else {
int byteCount = c_len &0x7f;
if (byteCount + idx > len) {
//rsa length field longer than buffer
returnnil;
}
unsignedint accum = 0;
unsignedchar *ptr = &c_key[idx];
idx += byteCount;
while (byteCount) {
accum = (accum << 8) + *ptr;
ptr++;
byteCount--;
}
c_len = accum;
}
// Now make a new NSData from this buffer
return [d_keysubdataWithRange:NSMakeRange(idx, c_len)];
}
+ (SecKeyRef)addPublicKey:(NSString *)key{
NSRange spos = [keyrangeOfString:@"-----BEGIN PUBLIC KEY-----"];
NSRange epos = [keyrangeOfString:@"-----END PUBLIC KEY-----"];
if(spos.location !=NSNotFound && epos.location !=NSNotFound){
NSUInteger s = spos.location + spos.length;
NSUInteger e = epos.location;
NSRange range =NSMakeRange(s, e-s);
key = [key substringWithRange:range];
}
key = [key stringByReplacingOccurrencesOfString:@"\r"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
// This will be base64 encoded, decode it.
NSData *data =base64_decode(key);
data = [RSAstripPublicKeyHeader:data];
if(!data){
returnnil;
}
//a tag to read/write keychain storage
NSString *tag =@"RSAUtil_PubKey";
NSData *d_tag = [NSDatadataWithBytes:[tag UTF8String] length:[taglength]];
// Delete any old lingering key with the same tag
NSMutableDictionary *publicKey = [[NSMutableDictionaryalloc] init];
[publicKey setObject:(__bridgeid) kSecClassKeyforKey:(__bridgeid)kSecClass];
[publicKey setObject:(__bridgeid) kSecAttrKeyTypeRSA forKey:(__bridgeid)kSecAttrKeyType];
[publicKey setObject:d_tagforKey:(__bridgeid)kSecAttrApplicationTag];
SecItemDelete((__bridgeCFDictionaryRef)publicKey);
// Add persistent version of the key to system keychain
[publicKey setObject:dataforKey:(__bridgeid)kSecValueData];
[publicKey setObject:(__bridgeid) kSecAttrKeyClassPublicforKey:(__bridgeid)
kSecAttrKeyClass];
[publicKey setObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)
kSecReturnPersistentRef];
CFTypeRef persistKey =nil;
OSStatus status =SecItemAdd((__bridgeCFDictionaryRef)publicKey, &persistKey);
if (persistKey !=nil){
CFRelease(persistKey);
}
if ((status !=noErr) && (status != errSecDuplicateItem)) {
returnnil;
}
[publicKey removeObjectForKey:(__bridgeid)kSecValueData];
[publicKey removeObjectForKey:(__bridgeid)kSecReturnPersistentRef];
[publicKey setObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)kSecReturnRef];
[publicKey setObject:(__bridgeid) kSecAttrKeyTypeRSA forKey:(__bridgeid)kSecAttrKeyType];
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef =nil;
status = SecItemCopyMatching((__bridgeCFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
if(status !=noErr){
returnnil;
}
return keyRef;
}
+ (SecKeyRef)addPrivateKey:(NSString *)key{
NSRange spos = [keyrangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];
NSRange epos = [keyrangeOfString:@"-----END RSA PRIVATE KEY-----"];
if(spos.location !=NSNotFound && epos.location !=NSNotFound){
NSUInteger s = spos.location + spos.length;
NSUInteger e = epos.location;
NSRange range =NSMakeRange(s, e-s);
key = [key substringWithRange:range];
}
key = [key stringByReplacingOccurrencesOfString:@"\r"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\n"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@"\t"withString:@""];
key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
// This will be base64 encoded, decode it.
NSData *data =base64_decode(key);
data = [RSAstripPrivateKeyHeader:data];
if(!data){
returnnil;
}
//a tag to read/write keychain storage
NSString *tag =@"RSAUtil_PrivKey";
NSData *d_tag = [NSDatadataWithBytes:[tag UTF8String] length:[taglength]];
// Delete any old lingering key with the same tag
NSMutableDictionary *privateKey = [[NSMutableDictionaryalloc] init];
[privateKey setObject:(__bridgeid) kSecClassKeyforKey:(__bridgeid)kSecClass];
[privateKey setObject:(__bridgeid) kSecAttrKeyTypeRSA forKey:(__bridgeid)kSecAttrKeyType];
[privateKey setObject:d_tagforKey:(__bridgeid)kSecAttrApplicationTag];
SecItemDelete((__bridgeCFDictionaryRef)privateKey);
// Add persistent version of the key to system keychain
[privateKey setObject:dataforKey:(__bridgeid)kSecValueData];
[privateKey setObject:(__bridgeid) kSecAttrKeyClassPrivateforKey:(__bridgeid)
kSecAttrKeyClass];
[privateKey setObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)
kSecReturnPersistentRef];
CFTypeRef persistKey =nil;
OSStatus status =SecItemAdd((__bridgeCFDictionaryRef)privateKey, &persistKey);
if (persistKey !=nil){
CFRelease(persistKey);
}
if ((status !=noErr) && (status != errSecDuplicateItem)) {
returnnil;
}
[privateKey removeObjectForKey:(__bridgeid)kSecValueData];
[privateKey removeObjectForKey:(__bridgeid)kSecReturnPersistentRef];
[privateKey setObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)kSecReturnRef];
[privateKey setObject:(__bridgeid) kSecAttrKeyTypeRSA forKey:(__bridgeid)kSecAttrKeyType];
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef =nil;
status = SecItemCopyMatching((__bridgeCFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
if(status !=noErr){
returnnil;
}
return keyRef;
}
/* START: Encryption & Decryption with RSA private key */
+ (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
constuint8_t *srcbuf = (constuint8_t *)[data bytes];
size_t srclen = (size_t)data.length;
size_t block_size =SecKeyGetBlockSize(keyRef) *sizeof(uint8_t);
void *outbuf =malloc(block_size);
size_t src_block_size = block_size -11;
NSMutableData *ret = [[NSMutableDataalloc] init];
for(int idx=0; idx<srclen; idx+=src_block_size){
//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
size_t data_len = srclen - idx;
if(data_len > src_block_size){
data_len = src_block_size;
}
size_t outlen = block_size;
OSStatus status =noErr;
status = SecKeyEncrypt(keyRef,
kSecPaddingPKCS1,
srcbuf + idx,
data_len,
outbuf,
&outlen
);
if (status !=0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
ret = nil;
break;
}else{
[ret appendBytes:outbuflength:outlen];
}
}
free(outbuf);
CFRelease(keyRef);
return ret;
}
+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [RSAencryptData:[strdataUsingEncoding:NSUTF8StringEncoding]privateKey:privKey];
NSString *ret =base64_encode_data(data);
return ret;
}
+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
returnnil;
}
SecKeyRef keyRef = [RSAaddPrivateKey:privKey];
if(!keyRef){
returnnil;
}
return [RSAencryptData:data withKeyRef:keyRef];
}
+ (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
constuint8_t *srcbuf = (constuint8_t *)[data bytes];
size_t srclen = (size_t)data.length;
size_t block_size =SecKeyGetBlockSize(keyRef) *sizeof(uint8_t);
UInt8 *outbuf =malloc(block_size);
size_t src_block_size = block_size;
NSMutableData *ret = [[NSMutableDataalloc] init];
for(int idx=0; idx<srclen; idx+=src_block_size){
//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
size_t data_len = srclen - idx;
if(data_len > src_block_size){
data_len = src_block_size;
}
size_t outlen = block_size;
OSStatus status =noErr;
status = SecKeyDecrypt(keyRef,
kSecPaddingNone,
srcbuf + idx,
data_len,
outbuf,
&outlen
);
if (status !=0) {
NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
ret = nil;
break;
}else{
//the actual decrypted data is in the middle, locate it!
int idxFirstZero = -1;
int idxNextZero = (int)outlen;
for (int i = 0; i < outlen; i++ ) {
if ( outbuf[i] ==0 ) {
if ( idxFirstZero <0 ) {
idxFirstZero = i;
} else {
idxNextZero = i;
break;
}
}
}
[ret appendBytes:&outbuf[idxFirstZero+1]length:idxNextZero-idxFirstZero-1];
}
}
free(outbuf);
CFRelease(keyRef);
return ret;
}
+ (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{
NSData *data = [[NSDataalloc] initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSAdecryptData:data privateKey:privKey];
NSString *ret = [[NSStringalloc] initWithData:dataencoding:NSUTF8StringEncoding];
return ret;
}
+ (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{
if(!data || !privKey){
returnnil;
}
SecKeyRef keyRef = [RSAaddPrivateKey:privKey];
if(!keyRef){
returnnil;
}
return [RSAdecryptData:data withKeyRef:keyRef];
}
/* END: Encryption & Decryption with RSA private key */
/* START: Encryption & Decryption with RSA public key */
+ (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [RSAencryptData:[strdataUsingEncoding:NSUTF8StringEncoding]publicKey:pubKey];
NSString *ret =base64_encode_data(data);
return ret;
}
+ (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
returnnil;
}
SecKeyRef keyRef = [RSAaddPublicKey:pubKey];
if(!keyRef){
returnnil;
}
return [RSAencryptData:data withKeyRef:keyRef];
}
+ (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{
NSData *data = [[NSDataalloc] initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];
data = [RSAdecryptData:data publicKey:pubKey];
NSString *ret = [[NSStringalloc] initWithData:dataencoding:NSUTF8StringEncoding];
return ret;
}
+ (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey{
if(!data || !pubKey){
returnnil;
}
SecKeyRef keyRef = [RSAaddPublicKey:pubKey];
if(!keyRef){
returnnil;
}
return [RSAdecryptData:data withKeyRef:keyRef];
}
/* END: Encryption & Decryption with RSA public key */
@end
//在这里调用
UILabel *enLabel =[[UILabel alloc]initWithFrame:CGRectMake(20, 100, 300, 40)];
NSString *labelText =@"今天没有下雨啊123456789";
[self.view addSubview:enLabel];
//公钥 加密
NSString *RSADataPubEN =[RSA encryptString:labelText publicKey:pubkey];
NSLog(@"加密%@",RSADataPubEN);
NSString *deString =@"BC5SLZEg5QnD4APupsxShKLWEdQuaSOOJ0EMV72t9UkFuqpspOcRqpt2A7p4q2Sa0ADRswPxHH9g8JCYSbLXcuJzM0gg73dbleLl+pM7bLogQmaRSgreifPR9Us6EeFTQ7ND04em2oxDf+KthzVORqrsPnzPe4ff877x1dBWovk=";
//公钥 解密
NSString *RSADataPubDN =[RSA decryptString:deString publicKey:pubkey];
NSLog(@"解密%@",RSADataPubDN);