iOS數(shù)據(jù)加密(Base64,散列函數(shù),AES,RSA)

Base64

base64是一種基于64個可打印字符來表示二進制數(shù)據(jù)的表示方法.嚴(yán)格來說它只能算作一種編碼方式.
Base64編碼之所以稱為Base64,是因為其使用64個字符來對任意數(shù)據(jù)進行編碼肄方,同理有Base32愁拭、Base16編碼

作用:

1, 由于某些系統(tǒng)中只能使用ASCII字符庭砍。Base64就是用來將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成ASCII字符的一種方法.
2, 使用SMTP協(xié)議 (Simple Mail Transfer Protocol 簡單郵件傳輸協(xié)議)來發(fā)送郵件噪叙。因為這個協(xié)議是基于文本的協(xié)議世澜,所以如果郵件中包含一幅圖片怔昨,我們知道圖片的存儲格式是二進制數(shù)據(jù)(binary data)雀久,而非文本格式,我們必須將二進制的數(shù)據(jù)編碼成文本格式趁舀,這時候Base 64 Encoding就派上用場了.
3, 通過base64將ASCII不可見字符轉(zhuǎn)換為可見字符

使用:

//編碼
- (NSString *)base64EncodedString;{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
return [data base64EncodedStringWithOptions:0];
}

//解碼
- (NSString *)base64DecodedString{
NSData *data = [[NSData alloc]initWithBase64EncodedString:self options:0];
return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}

MD5

MD5(消息摘要算法第五版)為計算機安全領(lǐng)域廣泛使用的一種散列函數(shù)赖捌,用以提供消息的完整性保護.

特點:

1、壓縮性:任意長度的數(shù)據(jù),算出的MD5值長度都是固定的(32摘要)越庇。
2罩锐、容易計算:從原數(shù)據(jù)計算出MD5值很容易。
3卤唉、抗修改性:對原數(shù)據(jù)進行任何改動涩惑,哪怕只修改1個字節(jié),所得到的MD5值都有很大區(qū)別桑驱。
4竭恬、強抗碰撞(難逆向):已知原數(shù)據(jù)和其MD5值,想找到一個具有相同MD5值的數(shù)據(jù)(即偽造數(shù)據(jù))是非常困難的熬的。

作用

1, 數(shù)字簽名, 當(dāng)我們傳遞敏感信息時,可以為利用MD5+時間戳+鹽 為消息添加唯一的數(shù)字簽名,當(dāng)服務(wù)端獲得數(shù)據(jù)后,用相同算法再次簽名.進行比較 若不一致 則數(shù)據(jù)遭到篡改.
2, 文件驗證, 我們在下載文件時,由于復(fù)雜的網(wǎng)絡(luò)環(huán)境,我們下載的文件可能會有內(nèi)容丟失或篡改的可能性.(例如我們從服務(wù)器獲取的H5文件遭到了JS注入),利用MD5可以有效防止這些事情的發(fā)生.

同類算法

SHA-1:

會產(chǎn)生一個160位的消息摘要,SHA-1的安全性在2000年以后已經(jīng)不被大多數(shù)的加密場景所接受痊硕。2017年荷蘭密碼學(xué)研究小組CWI和Google正式宣布攻破了SHA-1.

SHA-2:

2001年發(fā)布,包括SHA-224押框、SHA-256岔绸、SHA-384、SHA-512橡伞、SHA-512/224盒揉、SHA-512/256。雖然至今尚未出現(xiàn)對SHA-2有效的攻擊兑徘,它的算法跟SHA-1基本上仍然相似刚盈;因此有些人開始發(fā)展其他替代的散列算法。

SHA-3:

2015年正式發(fā)布道媚,SHA-3并不是要取代SHA-2扁掸,因為SHA-2目前并沒有出現(xiàn)明顯的弱點。由于對MD5出現(xiàn)成功的破解最域,以及對SHA-0和SHA-1出現(xiàn)理論上破解的方法谴分,NIST感覺需要一個與之前算法不同的,可替換的加密散列算法镀脂,也就是現(xiàn)在的SHA-3牺蹄。

實現(xiàn)

這里是對字符串的散列計算,若對文件則需要先讀取文件流再去散列.
需要: import <CommonCrypto/CommonDigest.h>

MD5

- (NSString *)md5String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), buffer);
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

SHA-1:

- (NSString *)sha1String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
    
    CC_SHA1(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
}

SHA256:

- (NSString *)sha256String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
    
    CC_SHA256(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
}

SHA512:

- (NSString *)sha512String {
    const char *str = self.UTF8String;
    uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
    
    CC_SHA512(str, (CC_LONG)strlen(str), buffer);
    
    return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
}

SHA3:

需要在github上下載keccak代碼包 :https://github.com/gvanas/KeccakCodePackage

大文件的計算:

這里以MD5為例:

#define FileHashDefaultChunkSizeForReadingData 4096

- (NSString *)fileMD5Hash {
    //打開一個文件準(zhǔn)備讀取
    NSFileHandle *fp = [NSFileHandle fileHandleForReadingAtPath:self];
    if (fp == nil) {
    //若路徑為文件夾這種的(如:.framework)則會返回Null
        return nil;
    }
    //創(chuàng)建MD5變量
    CC_MD5_CTX hashCtx;
    //初始化MD5變量
    CC_MD5_Init(&hashCtx);
    
    while (YES) {
        @autoreleasepool {
        //讀取文件指定長度數(shù)據(jù),循環(huán)讀取避免一次加載到內(nèi)存過大
            NSData *data = [fp readDataOfLength:FileHashDefaultChunkSizeForReadingData];
            //準(zhǔn)備MD5加密,將內(nèi)容上傳
            CC_MD5_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
            
            if (data.length == 0) {
                break;
            }
        }
    }
    //關(guān)閉文件
    [fp closeFile];
    
    //創(chuàng)建MD5結(jié)果緩沖區(qū)
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
    //將MD5結(jié)果寫進緩沖區(qū)
    CC_MD5_Final(buffer, &hashCtx);
    
    //原始數(shù)據(jù)轉(zhuǎn)換為字符串
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
    NSMutableString *strM = [NSMutableString string];
    
    for (int i = 0; i < length; i++) {
        [strM appendFormat:@"%02x", bytes[i]];
    }
    
    return [strM copy];
}

對于其他的算法文件加密方式也是這樣的,它們都是由CommonCrypto庫提供的.

HMAC散列計算(加鹽)

HMAC是密鑰相關(guān)的哈希運算消息認(rèn)證碼,HMAC運算利用哈希算法薄翅,以一個密鑰和一個消息為輸入沙兰,生成一個消息摘要作為輸出。
HMAC算法更象是一種加密算法翘魄,它引入了密鑰鼎天,其安全性已經(jīng)不完全依賴于所使用的HASH算法,有些類似對稱加密,但是是不可逆的那種~.
以MD5為例:

- (NSString *)hmacMD5StringWithKey:(NSString *)key {
    const char *keyData = key.UTF8String;
    const char *strData = self.UTF8String;
    //切換其他散列函數(shù)替換這里(如:CC_SHA256_DIGEST_LENGTH)
    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
        //切換其他散列函數(shù)替換這里(如:kCCHmacAlgSHA256)
    CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
    
   //切換其他散列函數(shù)替換這里(如:CC_SHA256_DIGEST_LENGTH)
    return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
}

AES(對稱加密)

簡介

美國國家標(biāo)準(zhǔn)技術(shù)研究所在2001年發(fā)布了高級加密標(biāo)準(zhǔn)(AES)。
AES是基于數(shù)據(jù)塊的加密方式暑竟,
即斋射,每次處理的數(shù)據(jù)是一塊(16字節(jié)),當(dāng)數(shù)據(jù)不是16字節(jié)的倍數(shù)時填充,
這就是所謂的分組密碼(區(qū)別于基于比特位的流密碼)罗岖,16字節(jié)是分組長度涧至。

AES在軟件及硬件上都能快速地加解密,相對來說較易于實現(xiàn)桑包,

15110869784780.jpg

實現(xiàn)

在使用AES時要配置幾個加密參數(shù),只有都一致才能使 客戶端與服務(wù)端 結(jié)果一致.

參數(shù)配置

密鑰長度

key常見的長度有三種:128南蓬、192和256 bits

加密模式

AES屬于塊加密(Block Cipher),塊加密中有CBC哑了、ECB赘方、CTR、OFB弱左、CFB等幾種工作模式.

ECB

是一種基礎(chǔ)的加密方式,AES默認(rèn)沒收,密文被分割成分組長度相等的塊(不足補齊)蒜焊,然后單獨一個個加密,一個個輸出組成密文.


15110873264632.jpg
CBC

這個模式是鏈?zhǔn)降?后一塊需要前一塊做基礎(chǔ),第一塊需要一個需要初始化向量IV做基礎(chǔ).
相同的輸入產(chǎn)生不同的輸出.
能看到的數(shù)據(jù)是“明文+IV”或“明文+前一個密文”的亂碼科贬,所以能隱藏明文.

所以加密/解密 需要: 明文/密文 + 秘鑰 + 初始向量參數(shù)


15110876564551.jpg

填充方式

因為AES的算法是把明文分組再處理的,他要求每個分組(16字節(jié))是“滿”的,即明文長度必須被16字節(jié)整除.

所以明文最后不足的16字節(jié)的要先進行數(shù)據(jù)填充,把不足16字節(jié)的最后一組補成16字節(jié).

CFB,OFB和CTR模式由于與key進行加密操作的是上一塊加密后的密文,因此不需要對最后一段明文進行填充.
在iOS SDK中提供了PKCS7Padding.

初始向量

正如在CBC模式哪里介紹的,開始加密時,從哪里開始就是初始向量,如不設(shè)置則系統(tǒng)默認(rèn)為0;

代碼

NSString *const kInitVector = @"初始向量";

size_t const kKeySize = kCCKeySizeAES256;//秘鑰長度

+ (NSData *)encryptAES:(NSData *)content key:(NSString *)key {
    
    NSData *contentData = content;
    NSUInteger dataLength = contentData.length;
    
    //設(shè)置加密秘鑰,因C字符串結(jié)束符為'\0' 所以大小+1
    char keyPtr[kKeySize + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    //應(yīng)確保大小小于等于16個字節(jié).
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    //密文長度 = 明文長度+秘鑰長度
    size_t encryptSize = dataLength + kCCBlockSizeAES128;
    void *encryptedBytes = malloc(encryptSize);
    
    //密文接受指針
    size_t actualOutSize = 0;
    
    //初始向量
    NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding];
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,               //是加密還是解密
                                          kCCAlgorithmAES,          //加密/解密方式
                                          kCCOptionPKCS7Padding,    //PKCS7Padding
                                          keyPtr,                   //秘鑰
                                          kKeySize,                 //秘鑰大小
                                          initVector.bytes,         //初始向量
                                          contentData.bytes,        //明文/密文
                                          dataLength,               //明文/密文大小
                                          encryptedBytes,           //結(jié)果: 密文/明文緩沖區(qū)
                                          encryptSize,              //結(jié)果: 密文/明文大小
                                          &actualOutSize);          //結(jié)果指針
    
    if (cryptStatus == kCCSuccess) {
        // 成功
        return [NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize];
    }
    //釋放
    free(encryptedBytes);
    return nil;
}

RSA

原理

數(shù)學(xué)基礎(chǔ)

任意給定正整數(shù)n,請問在小于等于n的正整數(shù)之中鳖悠,有多少個與n構(gòu)成互質(zhì)的數(shù).計算這個值的函數(shù)為 歐拉函數(shù): 如: φ(8) = 4.

若n為質(zhì)數(shù) 則: φ(n) = n-1 原理3
若n為質(zhì)數(shù)的n次方 則: φ(p^k) = p^k - p^(k-1)
若n為兩個互質(zhì)整數(shù)之積 則: φ(p1 * p2) = φ(p1)φ(p2) 原理1
若正整數(shù) a和n互質(zhì) 則: a^φ(n) 被n除的余數(shù)為1 則: a^φ(n) %n=1 歐拉定理
若正整數(shù)a和質(zhì)數(shù)p互質(zhì) 則: a^p-1 %p=1 //費馬小定理
若正整數(shù)a和n互質(zhì),則一定可以找到正整數(shù)b 使: ab%n=1, b為a的模反元素. 原理2

秘鑰生成

1, 隨機生成兩個不等質(zhì)數(shù)p和q 如 p=61 q=53

2, 求出pq乘積n n=p * q= 61*53=3233.

這里n的長度即為,秘鑰長度,如3233為二進制12位,RSA秘鑰一般為1024位.

3, 計算φ(n)

根據(jù) 原理1 φ(n) = φ(p)φ(q) = (p-1)(q-1) = 3120

4, 隨機選擇一個整數(shù)e 條件為 1<e<φ(n) 且 e與φ(n)互質(zhì)

假如選擇 17

5, 獲取e對于φ(n)的模反元素d

ed%φ(n)=1 ---> ed -1 = kφ(n) ---> 17d + 3120k = 1
通過擴展歐幾里德算法 可得到一組整數(shù)解 d=2753 k=-15

6, 這里 n和e 為公鑰 n和d 為私鑰

加密(此處為公鑰加密 n e)

對明文信息m 加密 注意:m為正整數(shù),且m須小于n

m^e % n = c 這里的c就是加密后得到的密文
65^17 % 3233 = 2790 這里2790就是加密后的密文

解密(n d)

解密原理

解密規(guī)則為: c^d %n = m

因為加密過程為: m^e % n = c ---> c = m^e - kn
若想證明解密規(guī)則成立 則等同于證明 (m^e - kn)^d % n = m 成立

(m^e - kn)^d % n = m ---> m^ed % n = m

由于在制作公私鑰 的第5步 所以:

ed%φ(n)=1 ---> ed = hφ(n)+1

將ed代入須證明公式:

m^ed % n = m ---> m^hφ(n)+1 % n = m

若m n 互質(zhì)

m^hφ(n)+1 % n = m ---> ((mφ(n))h * m) % n = m

由于歐拉定理 m^φ(n) %n=1可得
((mφ(n))h * m) % n = m ---> (1^h * m) % n = m 則解密公式成立

若m n 不互質(zhì)

因為制作公私鑰 的第1步 n = p * q

因為加密方法 m^e % n = c , 且因 m<n(這里是在制作時要求的) 所以 c肯定不為0 由此可得 m 與 n 不為互質(zhì)關(guān)系.

由于 n = pq 且 pq互質(zhì) 所以 n有且只有 p q 兩個因子. 然而 m n有公因子 所以 m n 的公因子 必定為 q或p的整數(shù)倍. 所以 m = kp 或 kq

以 m=kp為例 因為上面描述的關(guān)系 m<n , m n不互質(zhì), n = qp 所以 k與q互質(zhì) ---> m與q互質(zhì)

由歐拉定理得:
m^φ(q) % q = 1 ---> 由于q為質(zhì)數(shù) ---> m^q-1 % q = 1 --> (kp)^q-1 % q = 1

因為 k與q互質(zhì) p與q互質(zhì) --> ((kp)^q-1 * kp)%q = kp

進一步可以確定該式成立: (((kp)^h(p-1)(q-1)) * kp)%q = kp 因為p為質(zhì)數(shù) h為任一整數(shù)

原理1原理3(((kp)^h(p-1)(q-1)) * kp)%q = kp ---> (kp)^hφ(n)+1 %q=kp

由于 ed%φ(n)=1,且m=kp 所以將h匹配為合適的值得 (kp)^ed %q = kp ---> (m)^ed = tq +m t為整數(shù).

兩側(cè)同除m得: (m)^ed-1 = tq/m +1 由于ed為整數(shù),m為整數(shù) 故tq/m為整數(shù). 因q與m互質(zhì) 所以t為m的整數(shù)倍 --> t = yp ---> m^ed = yn+m ---> m^ed % n = m

由于加密方式 m^e % n = c ---> c^d % n = m

安全性討論

若想破解RSA 則需要在已知 n e的情況下 求 d 因為

因為 ed%φ(n)=1 所以需知道 φ(n)
因為 φ(n) = (p-1)(q-1) 所以需求得 qp
因為 qp=n 所以得將n因式分解

而因式分解是十分困難的 特別是對于 特大整數(shù)的因式分解. 由于 名文m 需小于 秘鑰長度n 所以常用來加密 對稱加密的秘鑰.

iOS實現(xiàn)

參考鏈接:iOS中使用RSA加密
在iOS中使用RSA加密解密 需要使用到.der.p12 后綴格式文件.

.p12 格式文件是用來加密的 私鑰
.der 格式文件用來解密的 公鑰

添加動態(tài)庫 Security.framework

具體實現(xiàn)太長,我匯總了一個類 github鏈接
感興趣可以下下來看看 如果幫到你 點個Star鼓勵一蛤~
本文地址
博客地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末榜掌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子乘综,更是在濱河造成了極大的恐慌憎账,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卡辰,死亡現(xiàn)場離奇詭異胞皱,居然都是意外死亡,警方通過查閱死者的電腦和手機九妈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門反砌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萌朱,你說我怎么就攤上這事宴树。” “怎么了晶疼?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵酒贬,是天一觀的道長。 經(jīng)常有香客問我翠霍,道長锭吨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任寒匙,我火速辦了婚禮零如,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己埠况,他們只是感情好耸携,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辕翰,像睡著了一般夺衍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喜命,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天沟沙,我揣著相機與錄音,去河邊找鬼壁榕。 笑死矛紫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的牌里。 我是一名探鬼主播颊咬,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼牡辽!你這毒婦竟也來了喳篇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤态辛,失蹤者是張志新(化名)和其女友劉穎麸澜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奏黑,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡炊邦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了熟史。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馁害。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蹂匹,靈堂內(nèi)的尸體忽然破棺而出蜗细,到底是詐尸還是另有隱情,我是刑警寧澤怒详,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布炉媒,位于F島的核電站,受9級特大地震影響昆烁,放射性物質(zhì)發(fā)生泄漏吊骤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一静尼、第九天 我趴在偏房一處隱蔽的房頂上張望白粉。 院中可真熱鬧传泊,春花似錦、人聲如沸鸭巴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鹃祖。三九已至溪椎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恬口,已是汗流浹背校读。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祖能,地道東北人歉秫。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像养铸,于是被迫代替她去往敵國和親雁芙。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

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

  • 這篇文章主要講述在Mobile BI(移動商務(wù)智能)開發(fā)過程中钞螟,在網(wǎng)絡(luò)通信却特、數(shù)據(jù)存儲、登錄驗證這幾個方面涉及的加密...
    雨_樹閱讀 2,351評論 0 6
  • 這是去年12月在CSDN寫的一篇加密算法文章 現(xiàn)在決定在簡書寫博客 移植過來方便復(fù)習(xí)再理解筛圆。 最近算法課老師要求小...
    icecrea閱讀 1,287評論 1 1
  • 前言 本文的RSA例子代碼更新在我的github上。 RSA算法是最重要算法之一椿浓,它是計算機通信安全的基石太援,保證了...
    game3108閱讀 11,619評論 2 53
  • 伴隨著移動產(chǎn)品廣泛應(yīng)用與快速發(fā)展,移動客戶端的安全問題越來越受重視扳碍。我這里主要談?wù)刬OS移動端的安全架構(gòu)設(shè)計提岔。 一...
    火星抄手閱讀 3,817評論 2 24
  • 昨天我們結(jié)束春節(jié)的出游,老公還提前一天到中途接我們笋敞,心情爽歪歪碱蒙。 車停在服務(wù)站時我瞄了一眼朋友圈,看...
    carol曉霞閱讀 409評論 4 6