RSA加密

在iOS中使用RSA加密解密,需要用到.der和.p12后綴格式的文件,其中.der格式的文件存放的是公鑰(Public key)用于加密,.p12格式的文件存放的是私鑰(Private key)用于解密. 首先需要先生成這些文件,然后再將文件導(dǎo)入工程使用功偿,不多說,開始做往堡!

一械荷、使用openssl生成所需秘鑰文件

生成環(huán)境是在mac系統(tǒng)下共耍,使用openssl進行生成,首先打開終端吨瞎,按下面這些步驟依次來做:

1. 生成模長為1024bit的私鑰文件private_key.pem

openssl genrsa -out private.pem 1024

2. 生成證書請求文件rsaCertReq.csr

openssl req -new -key private_key.pem -out rsaCerReq.csr

注意:這一步會提示輸入國家痹兜、省份、mail等信息颤诀,可以根據(jù)實際情況填寫字旭,或者全部不用填寫,直接全部敲回車.

3. 生成證書rsaCert.crt崖叫,并設(shè)置有效時間為10年

openssl x509 -req -days 3650 -in rsaCerReq.csr -signkey private_key.pem -out rsaCert.crt

4. 生成供iOS使用的公鑰文件public_key.der

openssl x509 -outform der -inrsaCert.crt-out public_key.der

5. 生成供iOS使用的私鑰文件private_key.p12

openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt

注意:這一步會提示給私鑰文件設(shè)置密碼遗淳,直接輸入想要設(shè)置密碼即可,然后敲回車心傀,然后再驗證剛才設(shè)置的密碼屈暗,再次輸入密碼,然后敲回車剧包,完畢恐锦!

在解密時往果,private_key.p12文件需要和這里設(shè)置的密碼配合使用疆液,因此需要牢記此密碼.

6. 生成供Java使用的公鑰rsa_public_key.pem

openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout

7. 生成供Java使用的私鑰pkcs8_private_key.pem

openssl pkcs8 -topk8 -inprivate_key.pem -out pkcs8_private_key.pem -nocrypt

全部執(zhí)行成功后,會生成如下文件陕贮,其中public_key.der和private_key.p12就是iOS需要用到的文件堕油,如下圖:

生成的文件

二、將文件導(dǎo)入工程使用

1.新建工程, 并導(dǎo)入Security.framework框架, 如下圖:

新建工程并添加框架

2.導(dǎo)入秘鑰文件

導(dǎo)入.der和.p12格式的秘鑰文件, 如下圖:

導(dǎo)入秘鑰文件

3.新建用于加密肮之、解密的類RSAEncryptor, 并實現(xiàn)相關(guān)方法

新建RSAEncryptor類, 如下圖:

新建用于加密解密的類

下面開始上代碼, 可以直接復(fù)制過去用:

RSAEncryptor.h代碼如下:

//

//RSAEncryptor.h

//毛票食堂

//

//Created by Apple on 17/2/11.

//Copyright ? 2017年P(guān)andora. All rights reserved.

//

#import

@interfaceRSAEncryptor :NSObject

/**

*加密方法

*

*@param str需要加密的字符串

*@param path'.der'格式的公鑰文件路徑

*/

+ (NSString*)encryptString:(NSString*)str publicKeyWithContentsOfFile:(NSString*)path;

/**

*解密方法

*

*@param str需要解密的字符串

*@param path'.p12'格式的私鑰文件路徑

*@param password私鑰文件密碼

*/

+ (NSString*)decryptString:(NSString*)str privateKeyWithContentsOfFile:(NSString*)path password:(NSString*)password;

/**

*加密方法

*

*@param str需要加密的字符串

*@param pubKey公鑰字符串

*/

+ (NSString*)encryptString:(NSString*)str publicKey:(NSString*)pubKey;

/**

*解密方法

*

*@param str需要解密的字符串

*@param privKey私鑰字符串

*/

+ (NSString*)decryptString:(NSString*)str privateKey:(NSString*)privKey;

@end

//

//RSAEncryptor.m

//毛票食堂

//

//Created by Apple on 17/2/11.

//Copyright ? 2017年P(guān)andora. All rights reserved.

//

#import"RSAEncryptor.h"

//RSAEncryptor.m代碼如下:

#import"RSAEncryptor.h"

#import

@implementationRSAEncryptor

staticNSString*base64_encode_data(NSData*data){

data = [database64EncodedDataWithOptions:0];

NSString*ret = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

returnret;

}

staticNSData*base64_decode(NSString*str){

NSData*data = [[NSDataalloc]initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];

returndata;

}

#pragma mark -使用'.der'公鑰文件加密

//加密

+ (NSString*)encryptString:(NSString*)str publicKeyWithContentsOfFile:(NSString*)path{

if(!str || !path)returnnil;

return[selfencryptString:strpublicKeyRef:[selfgetPublicKeyRefWithContentsOfFile:path]];

}

//獲取公鑰

+ (SecKeyRef)getPublicKeyRefWithContentsOfFile:(NSString*)filePath{

NSData*certData = [NSDatadataWithContentsOfFile:filePath];

if(!certData) {

returnnil;

}

SecCertificateRefcert =SecCertificateCreateWithData(NULL, (CFDataRef)certData);

SecKeyRefkey =NULL;

SecTrustReftrust =NULL;

SecPolicyRefpolicy =NULL;

if(cert !=NULL) {

policy =SecPolicyCreateBasicX509();

if(policy) {

if(SecTrustCreateWithCertificates((CFTypeRef)cert, policy, &trust) ==noErr) {

SecTrustResultTyperesult;

if(SecTrustEvaluate(trust, &result) ==noErr) {

key =SecTrustCopyPublicKey(trust);

}

}

}

}

if(policy)CFRelease(policy);

if(trust)CFRelease(trust);

if(cert)CFRelease(cert);

returnkey;

}

+ (NSString*)encryptString:(NSString*)str publicKeyRef:(SecKeyRef)publicKeyRef{

if(![strdataUsingEncoding:NSUTF8StringEncoding]){

returnnil;

}

if(!publicKeyRef){

returnnil;

}

NSData*data = [selfencryptData:[strdataUsingEncoding:NSUTF8StringEncoding]withKeyRef:publicKeyRef];

NSString*ret =base64_encode_data(data);

returnret;

}

#pragma mark -使用'.12'私鑰文件解密

//解密

+ (NSString*)decryptString:(NSString*)str privateKeyWithContentsOfFile:(NSString*)path password:(NSString*)password{

if(!str || !path)returnnil;

if(!password) password =@"";

return[selfdecryptString:strprivateKeyRef:[selfgetPrivateKeyRefWithContentsOfFile:pathpassword:password]];

}

//獲取私鑰

+ (SecKeyRef)getPrivateKeyRefWithContentsOfFile:(NSString*)filePath password:(NSString*)password{

NSData*p12Data = [NSDatadataWithContentsOfFile:filePath];

if(!p12Data) {

returnnil;

}

SecKeyRefprivateKeyRef =NULL;

NSMutableDictionary* options = [[NSMutableDictionaryalloc]init];

[optionssetObject: passwordforKey:(__bridgeid)kSecImportExportPassphrase];

CFArrayRefitems =CFArrayCreate(NULL,0,0,NULL);

OSStatussecurityError =SecPKCS12Import((__bridgeCFDataRef) p12Data, (__bridgeCFDictionaryRef)options, &items);

if(securityError ==noErr&&CFArrayGetCount(items) >0) {

CFDictionaryRefidentityDict =CFArrayGetValueAtIndex(items,0);

SecIdentityRefidentityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict,kSecImportItemIdentity);

securityError =SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);

if(securityError !=noErr) {

privateKeyRef =NULL;

}

}

CFRelease(items);

returnprivateKeyRef;

}

+ (NSString*)decryptString:(NSString*)str privateKeyRef:(SecKeyRef)privKeyRef{

NSData*data = [[NSDataalloc]initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];

if(!privKeyRef) {

returnnil;

}

data = [selfdecryptData:datawithKeyRef:privKeyRef];

NSString*ret = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

returnret;

}

#pragma mark -使用公鑰字符串加密

/* START: Encryption with RSA public key */

//使用公鑰字符串加密

+ (NSString*)encryptString:(NSString*)str publicKey:(NSString*)pubKey{

NSData*data = [selfencryptData:[strdataUsingEncoding:NSUTF8StringEncoding]publicKey:pubKey];

NSString*ret =base64_encode_data(data);

returnret;

}

+ (NSData*)encryptData:(NSData*)data publicKey:(NSString*)pubKey{

if(!data || !pubKey){

returnnil;

}

SecKeyRefkeyRef = [selfaddPublicKey:pubKey];

if(!keyRef){

returnnil;

}

return[selfencryptData:datawithKeyRef:keyRef];

}

+ (SecKeyRef)addPublicKey:(NSString*)key{

NSRangespos = [keyrangeOfString:@"-----BEGIN PUBLIC KEY-----"];

NSRangeepos = [keyrangeOfString:@"-----END PUBLIC KEY-----"];

if(spos.location!=NSNotFound&& epos.location!=NSNotFound){

NSUIntegers = spos.location+ spos.length;

NSUIntegere = epos.location;

NSRangerange =NSMakeRange(s, e-s);

key = [keysubstringWithRange:range];

}

key = [keystringByReplacingOccurrencesOfString:@"\r"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@"\n"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@"\t"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@" "withString:@""];

// This will be base64 encoded, decode it.

NSData*data =base64_decode(key);

data = [selfstripPublicKeyHeader:data];

if(!data){

returnnil;

}

//a tag to read/write keychain storage

NSString*tag =@"RSAUtil_PubKey";

NSData*d_tag = [NSDatadataWithBytes:[tagUTF8String]length:[taglength]];

// Delete any old lingering key with the same tag

NSMutableDictionary*publicKey = [[NSMutableDictionaryalloc]init];

[publicKeysetObject:(__bridgeid)kSecClassKeyforKey:(__bridgeid)kSecClass];

[publicKeysetObject:(__bridgeid)kSecAttrKeyTypeRSAforKey:(__bridgeid)kSecAttrKeyType];

[publicKeysetObject:d_tagforKey:(__bridgeid)kSecAttrApplicationTag];

SecItemDelete((__bridgeCFDictionaryRef)publicKey);

// Add persistent version of the key to system keychain

[publicKeysetObject:dataforKey:(__bridgeid)kSecValueData];

[publicKeysetObject:(__bridgeid)kSecAttrKeyClassPublicforKey:(__bridgeid)

kSecAttrKeyClass];

[publicKeysetObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)

kSecReturnPersistentRef];

CFTypeRefpersistKey =nil;

OSStatusstatus =SecItemAdd((__bridgeCFDictionaryRef)publicKey, &persistKey);

if(persistKey !=nil){

CFRelease(persistKey);

}

if((status !=noErr) && (status !=errSecDuplicateItem)) {

returnnil;

}

[publicKeyremoveObjectForKey:(__bridgeid)kSecValueData];

[publicKeyremoveObjectForKey:(__bridgeid)kSecReturnPersistentRef];

[publicKeysetObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)kSecReturnRef];

[publicKeysetObject:(__bridgeid)kSecAttrKeyTypeRSAforKey:(__bridgeid)kSecAttrKeyType];

// Now fetch the SecKeyRef version of the key

SecKeyRefkeyRef =nil;

status =SecItemCopyMatching((__bridgeCFDictionaryRef)publicKey, (CFTypeRef*)&keyRef);

if(status !=noErr){

returnnil;

}

returnkeyRef;

}

+ (NSData*)stripPublicKeyHeader:(NSData*)d_key{

// Skip ASN.1 public key header

if(d_key ==nil)return(nil);

unsignedlonglen = [d_keylength];

if(!len)return(nil);

unsignedchar*c_key = (unsignedchar*)[d_keybytes];

unsignedintidx=0;

if(c_key[idx++] !=0x30)return(nil);

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

elseidx++;

// PKCS #1 rsaEncryption szOID_RSA_RSA

staticunsignedcharseqiod[] =

{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;

elseidx++;

if(c_key[idx++] !='\0')return(nil);

// Now make a new NSData from this buffer

return([NSDatadataWithBytes:&c_key[idx]length:len - idx]);

}

+ (NSData*)encryptData:(NSData*)data withKeyRef:(SecKeyRef) keyRef{

constuint8_t*srcbuf = (constuint8_t*)[databytes];

size_tsrclen = (size_t)data.length;

size_tblock_size =SecKeyGetBlockSize(keyRef) *sizeof(uint8_t);

void*outbuf =malloc(block_size);

size_tsrc_block_size = block_size -11;

NSMutableData*ret = [[NSMutableDataalloc]init];

for(intidx=0; idx

//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);

size_tdata_len = srclen - idx;

if(data_len > src_block_size){

data_len = src_block_size;

}

size_toutlen = block_size;

OSStatusstatus =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{

[retappendBytes:outbuflength:outlen];

}

}

free(outbuf);

CFRelease(keyRef);

returnret;

}

/* END: Encryption with RSA public key */

#pragma mark -使用私鑰字符串解密

/* START: Decryption with RSA private key */

//使用私鑰字符串解密

+ (NSString*)decryptString:(NSString*)str privateKey:(NSString*)privKey{

if(!str)returnnil;

NSData*data = [[NSDataalloc]initWithBase64EncodedString:stroptions:NSDataBase64DecodingIgnoreUnknownCharacters];

data = [selfdecryptData:dataprivateKey:privKey];

NSString*ret = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];

returnret;

}

+ (NSData*)decryptData:(NSData*)data privateKey:(NSString*)privKey{

if(!data || !privKey){

returnnil;

}

SecKeyRefkeyRef = [selfaddPrivateKey:privKey];

if(!keyRef){

returnnil;

}

return[selfdecryptData:datawithKeyRef:keyRef];

}

+ (SecKeyRef)addPrivateKey:(NSString*)key{

NSRangespos = [keyrangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];

NSRangeepos = [keyrangeOfString:@"-----END RSA PRIVATE KEY-----"];

if(spos.location!=NSNotFound&& epos.location!=NSNotFound){

NSUIntegers = spos.location+ spos.length;

NSUIntegere = epos.location;

NSRangerange =NSMakeRange(s, e-s);

key = [keysubstringWithRange:range];

}

key = [keystringByReplacingOccurrencesOfString:@"\r"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@"\n"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@"\t"withString:@""];

key = [keystringByReplacingOccurrencesOfString:@" "withString:@""];

// This will be base64 encoded, decode it.

NSData*data =base64_decode(key);

data = [selfstripPrivateKeyHeader:data];

if(!data){

returnnil;

}

//a tag to read/write keychain storage

NSString*tag =@"RSAUtil_PrivKey";

NSData*d_tag = [NSDatadataWithBytes:[tagUTF8String]length:[taglength]];

// Delete any old lingering key with the same tag

NSMutableDictionary*privateKey = [[NSMutableDictionaryalloc]init];

[privateKeysetObject:(__bridgeid)kSecClassKeyforKey:(__bridgeid)kSecClass];

[privateKeysetObject:(__bridgeid)kSecAttrKeyTypeRSAforKey:(__bridgeid)kSecAttrKeyType];

[privateKeysetObject:d_tagforKey:(__bridgeid)kSecAttrApplicationTag];

SecItemDelete((__bridgeCFDictionaryRef)privateKey);

// Add persistent version of the key to system keychain

[privateKeysetObject:dataforKey:(__bridgeid)kSecValueData];

[privateKeysetObject:(__bridgeid)kSecAttrKeyClassPrivateforKey:(__bridgeid)

kSecAttrKeyClass];

[privateKeysetObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)

kSecReturnPersistentRef];

CFTypeRefpersistKey =nil;

OSStatusstatus =SecItemAdd((__bridgeCFDictionaryRef)privateKey, &persistKey);

if(persistKey !=nil){

CFRelease(persistKey);

}

if((status !=noErr) && (status !=errSecDuplicateItem)) {

returnnil;

}

[privateKeyremoveObjectForKey:(__bridgeid)kSecValueData];

[privateKeyremoveObjectForKey:(__bridgeid)kSecReturnPersistentRef];

[privateKeysetObject:[NSNumbernumberWithBool:YES]forKey:(__bridgeid)kSecReturnRef];

[privateKeysetObject:(__bridgeid)kSecAttrKeyTypeRSAforKey:(__bridgeid)kSecAttrKeyType];

// Now fetch the SecKeyRef version of the key

SecKeyRefkeyRef =nil;

status =SecItemCopyMatching((__bridgeCFDictionaryRef)privateKey, (CFTypeRef*)&keyRef);

if(status !=noErr){

returnnil;

}

returnkeyRef;

}

+ (NSData*)stripPrivateKeyHeader:(NSData*)d_key{

// Skip ASN.1 private key header

if(d_key ==nil)return(nil);

unsignedlonglen = [d_keylength];

if(!len)return(nil);

unsignedchar*c_key = (unsignedchar*)[d_keybytes];

unsignedintidx=22;//magic byte at offset 22

if(0x04!= c_key[idx++])returnnil;

//calculate length of the key

unsignedintc_len = c_key[idx++];

intdet = c_len &0x80;

if(!det) {

c_len = c_len &0x7f;

}else{

intbyteCount = c_len &0x7f;

if(byteCount + idx > len) {

//rsa length field longer than buffer

returnnil;

}

unsignedintaccum =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)];

}

+ (NSData*)decryptData:(NSData*)data withKeyRef:(SecKeyRef) keyRef{

constuint8_t*srcbuf = (constuint8_t*)[databytes];

size_tsrclen = (size_t)data.length;

size_tblock_size =SecKeyGetBlockSize(keyRef) *sizeof(uint8_t);

UInt8*outbuf =malloc(block_size);

size_tsrc_block_size = block_size;

NSMutableData*ret = [[NSMutableDataalloc]init];

for(intidx=0; idx

//NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);

size_tdata_len = srclen - idx;

if(data_len > src_block_size){

data_len = src_block_size;

}

size_toutlen = block_size;

OSStatusstatus =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!

intidxFirstZero = -1;

intidxNextZero = (int)outlen;

for(inti =0; i < outlen; i++ ) {

if( outbuf[i] ==0) {

if( idxFirstZero <0) {

idxFirstZero = i;

}else{

idxNextZero = i;

break;

}

}

}

[retappendBytes:&outbuf[idxFirstZero+1]length:idxNextZero-idxFirstZero-1];

}

}

free(outbuf);

CFRelease(keyRef);

returnret;

}

/* END: Decryption with RSA private key */

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掉缺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子戈擒,更是在濱河造成了極大的恐慌眶明,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筐高,死亡現(xiàn)場離奇詭異搜囱,居然都是意外死亡,警方通過查閱死者的電腦和手機柑土,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門蜀肘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稽屏,你說我怎么就攤上這事扮宠。” “怎么了狐榔?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵坛增,是天一觀的道長获雕。 經(jīng)常有香客問我,道長轿偎,這世上最難降的妖魔是什么典鸡? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮坏晦,結(jié)果婚禮上萝玷,老公的妹妹穿的比我還像新娘。我一直安慰自己昆婿,他們只是感情好球碉,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仓蛆,像睡著了一般睁冬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上看疙,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天豆拨,我揣著相機與錄音,去河邊找鬼能庆。 笑死施禾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的搁胆。 我是一名探鬼主播弥搞,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼渠旁!你這毒婦竟也來了攀例?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤顾腊,失蹤者是張志新(化名)和其女友劉穎粤铭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杂靶,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡梆惯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伪煤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片加袋。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖抱既,靈堂內(nèi)的尸體忽然破棺而出职烧,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布蚀之,位于F島的核電站蝗敢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏足删。R本人自食惡果不足惜寿谴,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望失受。 院中可真熱鬧讶泰,春花似錦、人聲如沸拂到。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兄旬。三九已至狼犯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間领铐,已是汗流浹背悯森。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绪撵,地道東北人瓢姻。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像莲兢,于是被迫代替她去往敵國和親汹来。 傳聞我的和親對象是個殘疾皇子续膳,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • /**ios常見的幾種加密方法: 普通的加密方法是講密碼進行加密后保存到用戶偏好設(shè)置( [NSUserDefaul...
    彬至睢陽閱讀 2,927評論 0 7
  • 嘟噥嘟噥:最近接到一個任務(wù):在客戶端動態(tài)生成RSA密鑰對改艇,然后向服務(wù)器發(fā)送這個密鑰對中的公鑰字符串,由服務(wù)器進行公...
    TimmyR閱讀 8,029評論 19 21
  • 數(shù)據(jù) 訓練1 1500m=breast975+free375+back15042:00 2.7p vs ptn1....
    帝都搬運工閱讀 186評論 0 0
  • 熊貓坟岔、南瓜和恐龍是 Steven 的三個毛絨玩具谒兄。這三個毛絨玩具是非常好的朋友,經(jīng)常在一起說笑聊天社付。但是承疲,他們的主...
    右旋左旋閱讀 424評論 0 1
  • 俊熙寶寶英語打卡:Dear: J.X. Today we have some new friends with u...
    Viver宣閱讀 250評論 0 0