ios Keychain存儲


iOS設(shè)備中的Keychain是一個安全的存儲容器根欧,可以用來為不同應(yīng)用保存敏感信息比如用戶名疾忍,密碼,網(wǎng)絡(luò)密碼横媚,認證令牌纠炮。蘋果自己用keychain來保存Wi-Fi網(wǎng)絡(luò)密碼,VPN憑證等等灯蝴。它是一個sqlite數(shù)據(jù)庫.

位于/private/var/Keychains/keychain-2.db恢口,其保存的所有數(shù)據(jù)都是加密過的。模擬器下keychain文件路徑:~/Library/Application Support/iPhone Simulator/4.3/Library/Keychains

keychain里保存的信息不會因App被刪除而丟失穷躁,在用戶重新安裝App后依然有效耕肩,數(shù)據(jù)還在。

關(guān)于備份折砸,?只會備份數(shù)據(jù)看疗,到那時不會備份設(shè)備的密鑰,換句話說睦授,即使拿到數(shù)據(jù)两芳,也沒有辦法解密里面的內(nèi)容。



?密鑰類型

密鑰類型的鍵 ? ?CFTypeRef kSecClass

密鑰類型的值:

//CFTypeRef kSecClassGenericPassword? ? ? ? ? ? //一般密碼

//CFTypeRef kSecClassInternetPassword? ? ? ? ? //網(wǎng)絡(luò)密碼

//CFTypeRef kSecClassCertificate? ? ? ? ? ? ? ? //證書

//CFTypeRef kSecClassKey? ? ? ? ? ? ? ? ? ? ? ? //密鑰

//CFTypeRef kSecClassIdentity? ? ? ? ? ? ? ? ? //身份證書(帶私鑰的證書)


不同類型的鑰匙串項對應(yīng)的屬性不同

1.一般密碼?kSecClassGenericPassword

a.對應(yīng)屬性

//kSecAttrAccessible

//kSecAttrAccessGroup

//kSecAttrCreationDate

//kSecAttrModificationDate

//kSecAttrDescription

//kSecAttrComment

//kSecAttrCreator

//kSecAttrType

//kSecAttrLabel

//kSecAttrIsInvisible

//kSecAttrIsNegative

//kSecAttrAccount

//kSecAttrService

//kSecAttrGeneric

2.網(wǎng)絡(luò)密碼 ?kSecClassInternetPassword

a.對應(yīng)屬性

//kSecAttrAccessible

//kSecAttrAccessGroup

//kSecAttrCreationDate

//kSecAttrModificationDate

//kSecAttrDescription

//kSecAttrComment

//kSecAttrCreator

//kSecAttrType

//kSecAttrLabel

//kSecAttrIsInvisible

//kSecAttrIsNegative

//kSecAttrAccount

//kSecAttrSecurityDomain

//kSecAttrServer

//kSecAttrProtocol

//kSecAttrAuthenticationType

//kSecAttrPort

//kSecAttrPath

3.證書 ?kSecClassCertificate

c.對應(yīng)屬性

//kSecAttrAccessible

//kSecAttrAccessGroup

//kSecAttrCertificateType

//kSecAttrCertificateEncoding

//kSecAttrLabel

//kSecAttrSubject

//kSecAttrIssuer

//kSecAttrSerialNumber

//kSecAttrSubjectKeyID

//kSecAttrPublicKeyHash

4.密鑰 ??kSecClassKey

d.對應(yīng)屬性

//kSecAttrAccessible

//kSecAttrAccessGroup

//kSecAttrKeyClass

//kSecAttrLabel

//kSecAttrApplicationLabel

//kSecAttrIsPermanent

//kSecAttrApplicationTag

//kSecAttrKeyType

//kSecAttrKeySizeInBits

//kSecAttrEffectiveKeySize

//kSecAttrCanEncrypt

//kSecAttrCanDecrypt

//kSecAttrCanDerive

//kSecAttrCanSign

//kSecAttrCanVerify

//kSecAttrCanWrap

//kSecAttrCanUnwrap


?證書屬性

1.私鑰屬性

鍵 ?CFTypeRef kSecAttrAccessible ? ? ? ? ? //可訪問性 類型透明

//? ? ? ? ? CFTypeRef kSecAttrAccessibleWhenUnlocked;? ? ? ? ? ? ? ? ? //解鎖可訪問去枷,備份

//? ? ? ? ? CFTypeRef kSecAttrAccessibleAfterFirstUnlock; ? ? ? ? ? //第一次解鎖后可訪問怖辆,備份

//? ? ? ? ? CFTypeRef kSecAttrAccessibleAlways; ? ? ? ? ? ? ? ? ? //一直可訪問是复,備份

//? ? ? ? ? CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly;? ? //解鎖可訪問,不備份

//? ? ? ? ? CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;//第一次解鎖后可訪問竖螃,不備份

//? ? ? ? ? CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly;? ? ? ? ? //一直可訪問淑廊,不備份

//CFTypeRef kSecAttrCreationDate;? ? ? //創(chuàng)建日期? ? ? ? ? CFDateRef

//CFTypeRef kSecAttrModificationDate;? //最后一次修改日期? CFDateRef

//CFTypeRef kSecAttrDescription;? ? ? //描述? ? ? ? ? ? CFStringRef

//CFTypeRef kSecAttrComment;? ? ? ? ? //注釋? ? ? ? ? ? CFStringRef

//CFTypeRef kSecAttrCreator;? ? ? ? ? //創(chuàng)建者? ? ? ? ? ? CFNumberRef(4字符,如'aLXY')

//CFTypeRef kSecAttrType;? ? ? ? ? ? ? //類型? ? ? ? ? ? CFNumberRef(4字符特咆,如'aTyp')

//CFTypeRef kSecAttrLabel;? ? ? ? ? ? //標簽(給用戶看)? ? CFStringRef

//CFTypeRef kSecAttrIsInvisible;? ? ? //是否隱藏? ? ? ? ? CFBooleanRef(kCFBooleanTrue,kCFBooleanFalse)

//CFTypeRef kSecAttrIsNegative;? ? ? ? //是否具有密碼? ? ? CFBooleanRef(kCFBooleanTrue,kCFBooleanFalse)此項表示當前的item是否只是一個占位項季惩,或者說是只有key沒有value。

//CFTypeRef kSecAttrAccount;? ? ? ? ? //賬戶名? ? ? ? ? ? CFStringRef

//CFTypeRef kSecAttrService;? ? ? ? ? //所具有服務(wù)? ? ? ? CFStringRef

//CFTypeRef kSecAttrGeneric;? ? ? ? ? //用戶自定義內(nèi)容? ? ? CFDataRef

//CFTypeRef kSecAttrSecurityDomain;? ? //網(wǎng)絡(luò)安全域? ? ? ? CFStringRef

//CFTypeRef kSecAttrServer;? ? ? ? ? ? //服務(wù)器域名或IP地址? CFStringRef

//鍵 CFTypeRef kSecAttrProtocol; ? ? ? ? ? ? ? //協(xié)議類型 CFNumberRef

?值

//? ? ? ? ? CFTypeRef kSecAttrProtocolFTP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolFTPAccount;?

//? ? ? ? ? CFTypeRef kSecAttrProtocolHTTP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolIRC; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolNNTP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolPOP3; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolSMTP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolSOCKS; ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolIMAP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolLDAP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolAppleTalk; ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolAFP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolTelnet; ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolSSH; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolFTPS; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolHTTPS; ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolHTTPProxy; ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolHTTPSProxy; ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolFTPProxy; ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolSMB; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolRTSP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolRTSPProxy; ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolDAAP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolEPPC; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolIPP; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolNNTPS; ? ??

//? ? ? ? ? CFTypeRef kSecAttrProtocolLDAPS; ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolTelnetS; ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolIMAPS; ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolIRCS; ? ? ? ?

//? ? ? ? ? CFTypeRef kSecAttrProtocolPOP3S; ? ? ?

//鍵 CFTypeRef kSecAttrAuthenticationType ? ? ? ?

?認證類型 CFNumberRef

?值

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeNTLM;? ? ? ? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeMSN;? ? ? ? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeDPA;? ? ? ? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeRPA;? ? ? ? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeHTTPBasic;? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeHTTPDigest;? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeHTMLForm;? ? //

//? ? ? ? ? CFTypeRef kSecAttrAuthenticationTypeDefault;? ? //

//CFTypeRef kSecAttrPort;? ? ? ? ? ? ? ? //網(wǎng)絡(luò)端口? ? ? ? ? CFNumberRef

//CFTypeRef kSecAttrPath;? ? ? ? ? ? ? ? //訪問路徑? ? ? ? ? CFStringRef

//CFTypeRef kSecAttrSubject;? ? ? ? ? ? ? //X.500主題名稱? ? ? CFDataRef

//CFTypeRef kSecAttrIssuer;? ? ? ? ? ? ? //X.500發(fā)行者名稱? ? CFDataRef

//CFTypeRef kSecAttrSerialNumber;? ? ? ? //序列號? ? ? ? ? ? CFDataRef

//CFTypeRef kSecAttrSubjectKeyID;? ? ? ? //主題ID? ? ? ? ? ? CFDataRef

//CFTypeRef kSecAttrPublicKeyHash;? ? ? ? //公鑰Hash值? ? ? ? CFDataRef

//CFTypeRef kSecAttrCertificateType;? ? ? //證書類型? ? ? ? ? ? CFNumberRef

//CFTypeRef kSecAttrCertificateEncoding;? //證書編碼類型? ? ? ? CFNumberRef

//CFTypeRef kSecAttrKeyClass ? ? ? ? ? ? //加密密鑰類? CFTypeRef

//? ? ? ? ? CFTypeRef kSecAttrKeyClassPublic;? ? //公鑰

//? ? ? ? ? CFTypeRef kSecAttrKeyClassPrivate;? ? //私鑰

//? ? ? ? ? CFTypeRef kSecAttrKeyClassSymmetric;? //對稱密鑰

//CFTypeRef kSecAttrApplicationLabel;? //標簽(給程序使用)? ? ? ? ? CFStringRef(通常是公鑰的Hash值)

//CFTypeRef kSecAttrIsPermanent;? ? ? //是否永久保存加密密鑰? ? ? CFBooleanRef

//CFTypeRef kSecAttrApplicationTag;? ? //標簽(私有標簽數(shù)據(jù))? ? ? ? CFDataRef

//CFTypeRef kSecAttrKeyType ?//加密密鑰類型(算法)? CFNumberRef

?值

//? ? ? ? ? extern const CFTypeRef kSecAttrKeyTypeRSA;

//CFTypeRef kSecAttrKeySizeInBits;? ? //密鑰總位數(shù)? ? ? ? ? ? ? CFNumberRef

//CFTypeRef kSecAttrEffectiveKeySize;? //密鑰有效位數(shù)? ? ? ? ? ? ? CFNumberRef

//CFTypeRef kSecAttrCanEncrypt;? ? ? ? //密鑰是否可用于加密? ? ? ? CFBooleanRef

//CFTypeRef kSecAttrCanDecrypt;? ? ? ? //密鑰是否可用于加密? ? ? ? CFBooleanRef

//CFTypeRef kSecAttrCanDerive;? ? ? ? //密鑰是否可用于導(dǎo)出其他密鑰? CFBooleanRef

//CFTypeRef kSecAttrCanSign;? ? ? ? ? //密鑰是否可用于數(shù)字簽名? ? ? CFBooleanRef

//CFTypeRef kSecAttrCanVerify;? ? ? ? //密鑰是否可用于驗證數(shù)字簽名? CFBooleanRef

//CFTypeRef kSecAttrCanWrap;? ? ? ? ? //密鑰是否可用于打包其他密鑰? CFBooleanRef

//CFTypeRef kSecAttrCanUnwrap;? ? ? ? //密鑰是否可用于解包其他密鑰? CFBooleanRef

//CFTypeRef kSecAttrAccessGroup;? ? ? //訪問組? ? ? ? ? ? ? ? ? CFStringRef

搜索

//CFTypeRef kSecMatchPolicy;? ? ? ? ? ? ? ? //指定策略? ? ? ? ? ? SecPolicyRef

//CFTypeRef kSecMatchItemList;? ? ? ? ? ? ? //指定搜索范圍? ? ? ? CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef,CFDataRef)數(shù)組內(nèi)的類型必須唯一腻格。仍然會搜索鑰匙串画拾,但是搜索結(jié)果需要與該數(shù)組取交集作為最終結(jié)果。

//CFTypeRef kSecMatchSearchList;? ? ? ? ? ? //

//CFTypeRef kSecMatchIssuers;? ? ? ? ? ? ? ? //指定發(fā)行人數(shù)組? ? ? CFArrayRef

//CFTypeRef kSecMatchEmailAddressIfPresent;? //指定郵件地址? ? ? ? CFStringRef

//CFTypeRef kSecMatchSubjectContains;? ? ? ? //指定主題? ? ? ? ? ? CFStringRef

//CFTypeRef kSecMatchCaseInsensitive;? ? ? ? //指定是否不區(qū)分大小寫? CFBooleanRef(kCFBooleanFalse或不提供此參數(shù),區(qū)分大小寫;kCFBooleanTrue,不區(qū)分大小寫)

//CFTypeRef kSecMatchTrustedOnly;? ? ? ? ? ? //指定只搜索可信證書? ? CFBooleanRef(kCFBooleanFalse或不提供此參數(shù),全部證書;kCFBooleanTrue,只搜索可信證書)

//CFTypeRef kSecMatchValidOnDate;? ? ? ? ? ? //指定有效日期? ? ? ? CFDateRef(kCFNull表示今天)

//CFTypeRef kSecMatchLimit;? ? ? ? ? ? ? ? ? //指定結(jié)果數(shù)量? ? ? ? CFNumberRef(kSecMatchLimitOne;kSecMatchLimitAll)

//CFTypeRef kSecMatchLimitOne;? ? ? ? ? ? ? //首條結(jié)果

//CFTypeRef kSecMatchLimitAll;? ? ? ? ? ? ? //全部結(jié)果

列表

//CFTypeRef kSecUseItemList;? //CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef,CFDataRef)數(shù)組內(nèi)的類型必須唯一菜职。用戶提供用于查詢的列表青抛。當這個列表被提供的時候,不會再搜索鑰匙串酬核。

?返回值類型

//可以同時指定多種返回值類型

//CFTypeRef kSecReturnData;? ? ? ? ? //返回數(shù)據(jù)(CFDataRef)? ? ? ? ? ? ? ? ? CFBooleanRef

//CFTypeRef kSecReturnAttributes;? ? //返回屬性字典(CFDictionaryRef)? ? ? ? CFBooleanRef

//CFTypeRef kSecReturnRef;? ? ? ? ? ? //返回實例(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef, or CFDataRef)? ? ? ? CFBooleanRef

//CFTypeRef kSecReturnPersistentRef;? //返回持久型實例(CFDataRef)? ? ? ? ? ? CFBooleanRef

寫入值類型

//CFTypeRef kSecValueData;

//CFTypeRef kSecValueRef;

//CFTypeRef kSecValuePersistentRef;

-------------------------------------------------------------------

簡單實現(xiàn):

在”Build Phases“中導(dǎo)入庫"Security.framework"

+ (BOOL)save:(NSString*)service data:(id)data;

+ (id)load:(NSString*)service;

+ (void)delete:(NSString*)service;




+ (NSMutableDictionary*) getKeychainQuery: (NSString*)service {

return [NSMutableDictionary dictionaryWithObjectsAndKeys:

(id)kSecClassGenericPassword, (id)kSecClass,

service, (id)kSecAttrService,

service, (id)kSecAttrAccount,

(id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,

nil nil];

}

+ (BOOL) save:(NSString*)service data:(id)data {

NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

SecItemDelete((CFDictionaryRef)keychainQuery);

[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];

return SecItemAdd((CFDictionaryRef)keychainQuery, NULL) == noErr;

}

+ (id) load:(NSString*)service {

id ret = NULL;

NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];

[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];

NSData *keyData = NULL;

if(SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef*)(void*)&keyData) == noErr) {

@try {

ret = [NSKeyedUnarchiver unarchiveObjectWithData:keyData];

}

@catch (NSException *exception) {

NSLog(@"Unarchive of %@ failed: %@", service, exception);

}

@finally {

}

}

return ret;

}

+ (void) delete:(NSString*)service {

NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

SecItemDelete((CFDictionaryRef)keychainQuery);

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜜另,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嫡意,更是在濱河造成了極大的恐慌举瑰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹅很,死亡現(xiàn)場離奇詭異嘶居,居然都是意外死亡,警方通過查閱死者的電腦和手機促煮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門邮屁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人菠齿,你說我怎么就攤上這事佑吝。” “怎么了绳匀?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵芋忿,是天一觀的道長。 經(jīng)常有香客問我疾棵,道長戈钢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任是尔,我火速辦了婚禮殉了,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拟枚。我一直安慰自己薪铜,他們只是感情好众弓,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著隔箍,像睡著了一般谓娃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜒滩,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天滨达,我揣著相機與錄音,去河邊找鬼帮掉。 笑死弦悉,一個胖子當著我的面吹牛窒典,可吹牛的內(nèi)容都是我干的蟆炊。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼瀑志,長吁一口氣:“原來是場噩夢啊……” “哼涩搓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起劈猪,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤昧甘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后战得,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體充边,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年常侦,在試婚紗的時候發(fā)現(xiàn)自己被綠了浇冰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡聋亡,死狀恐怖肘习,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坡倔,我是刑警寧澤漂佩,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站罪塔,受9級特大地震影響投蝉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜征堪,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一瘩缆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧请契,春花似錦咳榜、人聲如沸夏醉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽畔柔。三九已至,卻和暖如春臣樱,著一層夾襖步出監(jiān)牢的瞬間靶擦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工雇毫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留玄捕,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓棚放,卻偏偏與公主長得像枚粘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子飘蚯,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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