iOS应用签名原理--数字签名?代码签名?双层代码签名?

应用签名

数字签名

数字签名(又称公钥数字签名、电子签章等)是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术实现,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。
数字签名,就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。

数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用Hash函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。

举个例子:移动客户端向服务器发送数据

客户端发送数据

如果不做任何处理,可能会遭到中间人的窃取攻击,后果如何严重就不说了。那么我们如何防止中间人拦截,或者检查数据是否被篡改呢?
直接用RSA(RSA加密原理)进行加密应该是不满足我们的需求,RSA只适合对小数据进行加密,我们知道验证数据的完整性可以用Hash(Hash概述)来验证,可以对数据进行Hash,把Hash值和原始数据一起打包发送给服务器,服务器将原始数据进行Hash,得到的hash值和客户端发送的Hash值做对比,如果一致则保证数据有效性。但是这样会有安全隐患,如果中间人篡改了客户端发送的数据,当然也可以修改客户端发送的Hash值,所以这样操作不可行。

这时我们可以用RSA来对hash值进行保护,此时客户端发送原始数据,和经RSA加密后的该数据的hash值。

数字签名

服务器对RSA加密的数据进行解密,得到原始数据的hash值,接下来对原始数据进行通过同样的Hash算法,将得到的Hash值和解密后的Hash值做对比,如果一致则保证数据有效性,整个过程中,如果解密的Hash值和原始的Hash值不一致,或者无法解密RSA的数据,说明数据被篡改了。

3.jpg

现在我们解决了服务端收到客户端发送数据的有效性,此时我们称,对原始数据Hash值进行RSA加密后的数据,是原始数据的数字签名。简单解释数字签名也就是对原始数据的Hash值进行非对称加密。

代码签名

代码签名是对可执行文件或脚本进行数字签名,用来标识软件来源以及软件开发者的真实身份,确认软件在签名后未被修改或损坏的措施。和数字签名原来一样,只不过签名的数据是代码而已。

苹果也是通过代码签名来保证每一个安装到iOS上的APP都是经过苹果官方允许的,防止盗版软件、病毒入侵、静默安装等。如果想要实现验证,最简单的方式就是通过苹果官方生成非对称加密的一对公私钥,在iOS系统中内置一个与服务器对应的公钥,私钥由苹果后台来保存,我们传APP到App Store时,苹果后来用私钥对APP数据进行签名,iOS系统下载这个APP后,用公钥验证这个签名,如果签名正确则这个APP肯定是由苹果后台认证的,并且没有被修改或损坏。

代码签名

整个过程很简单,这样就保证了苹果安装的每一个APP都是经过苹果官方允许的。对于大部分普通用户而言,这样一个数字签名就解决了安全隐患问题,但是实际上iOS设备安装APP并不是只有App Store这一个渠道,比如对于我们iOSer来说,我们在开发APP时还在真机调试,当然苹果还开放了企业内部分发的渠道,这时就无法通过简单的代码签名来满足这些需求了。

苹果为了实现这些需求,iOS签名的复杂度也就开始增加了,这样双层代码签名就出现了。前提,我们都知道描述文件,但是描述文件具体是干嘛的呢

描述文件

在真机调试时候,都会有一个描述文件,描述文件就是在developer.apple.com创建的,在Xcode中填入AppID后会代办创建,Xcode运行时会打包进APP中。为了系统安全,苹果除了控制APP滥用问题还控制了推送、iCloud、调试器等附加这些权限,苹果把这些权限开关统一称为Entitlements(授权文件)。并将这个文件放在了一个叫做Provisioning Profile(描述文件)文件中,描述文件里面就包括权限、证书等配置相关文件。

通常,描述文件会保存在~/Library/MobileDevice/Provisioning Profiles/这个文件中,可以在终端用 security cms -D -i + [名称]命令查看描述文件里面的信息,我们会发现,描述文件是一个plist文件,下面是个人描述文件信息演示,并对一些信息做出了注释,部分关键内容被隐藏,Base64(了解Base64编码解码)内容被删减

$ security cms -D -i 294b2de0-a877-4f33-9825-9a8***.mobileprovision 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>AppIDName</key>
    <string>com *** </string>
    <key>ApplicationIdentifierPrefix</key>
    <array>
    <string>***GCDB</string>
    </array>
    <key>CreationDate</key>
    <date>2019-03-06T08:54:06Z</date>
    <key>Platform</key>
    <array>
        <string>iOS</string>
    </array>
    <key>IsXcodeManaged</key>
    <true/>
    <key>DeveloperCertificates</key>
    <array>
        <data>***vcNAQELBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNzEwMDIzNsb3BtZW50IENvLixMdGQuMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO4xNm+/SXHwULul2Am4b+2/a919AfaDSy6Jw+nC3599RNhUlY+/PNTudcsBUsSw53+flAh6dVVGO77lebM1GaveXMLr65l9aZe2a6ewR0QOpSkvoBZBXlRA14WpyfdMbU7VlWutKiFHsuxA4KSQyoagY8GJ3tB5vSlxRtfix0TKtOCMx9v1iYdCztmhmtt5J6GZn8jKszkPgKxMNvm4MD9N/pr7/Z0gX06oywYb3DpS7uQKdffsLZyj05H0HvSg6V4nHZw5HNIf8qd1VjOiI7NGcvsOwltfGmiOhmxQjaESwalgX7vWg7ij8fh9ke1on8veQgptIxutKjLWG9JnJ2LPOeP7w3PJC03Yl89qJ6F0VAyA1+ck1ieimrG0yXkd9z/YWMd/puDoW7SmEQ/WdKyQkyld0iSnkQ90511uOAp0/yDgaaouyUDZlcIjL2/4JzdEJEiRkZEdmw63uYe4dwXSyTyLlA+ntka2QlKEiJmy8oyPTqjEuqcWWQmnFYWiEBqPaeEXlXT9uuGjqn9aN3MaTgD8QFIyOhonc6ReQHtx8apXGEzhVNAQXCLuKSB04JiCbL3YE2XT42QlygBL+7ROxC00pAIltrPkFfuoyBbpnj9pWQ==</data>
        <data>***GVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNTI1MTMxMjA4WhcNMTkwNTI1MTMxMjA4WjCBrjEaMBgGCgmSJomT8ixkAQEMCjVFVE45NEpBNlUxMTAvBgNVBAMMKGlQaG9uZSBEZXZlbG9wZXI6IFhpbiBDaGVuZyAoNEU4Mk5RVzZDMikxEzARBgNVBAsMClpFV0pNSEdDREIxOzA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBvd2VyIERldmVsb3BtZW50IENvMDYGCCsGAQUFBwIBFipodHRwOi8dEU39NyqZsQBCA/P1txkkx9sI7JsMcMnjwa/N5QCg+gJLvMEh1ZvQ/rroTtyvDxFuuMrQkiZeeBGs8qBO2Jre6ma32mMo5kSjc9w9AtnFwlQHrW3+HPwwqlThRrMeNvbLZAvZhoENb04HE26sH4k1tk8CrNvutsjl+K3GGnuvWCnZy/dT57wrGAMrlkQZRWXomSxr9y+F4ArsMj+4UsA==</data>
        <data>***sZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNTEzMDQ1OTQ0WhcNMTkwNTEzMDQ1OTQ0WjCBrjEaMBgGCgmSJomT8ixkAQEMCjVFVE45NEpBNlUxMTAvBgNVBAMMKGlQaG9uZSBEZXZlbG9wZXI6IFhpbiBDaGVuZyAoNEU4Mk5RVzZDMikxEzARBgNVBAsMClpFV0pNSEdDREIxOzA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwMwHQYzizUHwwrgDSFxwfGfc71fr4hz3PmN6o7XqtGcNO4Af49JdDMZv6VQ5mr/plPBSDdun0D5ZfNDr9cXopDCzy+XPZB/H1ARmy1MT4vuKvdsGuUKBvJX/HinDi38G6AuwZ0alfPY9xqJ7WB7K14kaVdaaqOHMThOA7b7b1Stu+MjAKYJ6aUkrf9vvDbDAkQFi8lfh4L3Vya9MoXEpDpCNxQrUJhc6sy2eMf1NT5Q==</data>
        <data>***zA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBvd2VyIERldmVsb3BtZW50IENvLixMdGQuMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKIWs9nQdTq3yqKLYVmjrGrgh6MhaWlkZb5MeHWKwGfky3/n/FaXmrLNxFFFWeFihdg4zmFjSjRl8ccvPF3afdZU2qW4Co1aKu459CnPhknFNbFtcrs0V1T6u6p3RJn6togsWn1z33IakruJPYtwY7k4S5jb20vb2NzcDAzLXd3ZHIwMTCCAR0GA1UdIASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGVAFqGwKrYTc+8/GyszOm3u4/mn5s5b58ORnITE+A9bNtDGv6Qz46ev3ZMCrQZFwye//Tk+BI7ms4++jkj/pcmUCULtZw178cTRBpMT4P7tzgH5mRP/BpcSd/rv8994UXYPYdpXa4epFhchlCvu8dT8sQ38fFeahyd85nS30c4RxyW32bzKnzzRSedr/j4Y1qIIvzKdWPcnwkA5RYH8naxYfzEXL2321tdwfR5skvApeP/S2oX9WC+18XBk8Yy693rJoqrKdwkOzQSVGcA==</data>
        <data>***3NjZOMlBGS00xMzAxBgNVBAMMKmlQaG9uZSBEZXZlbG9wZXI6IEhhb3lhbmcgWmh1IChLTU5VVTI4QlBaKTETMBEGA1UECwwKWkVXSk1IR0NEQjE7MDkGA1UECgwyU2hhbmdoYWkgUmlzZW4gRWxlY3RyaWMgUG93ZXIgRGV2ZWxvcG1lbnQgQ28uLEx0ZC4xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19bNzMNJ0uSYvwNygYH8b4GQY11UmNvbS9vY3NwMDMtd3dkcjAxMIIBHQYDVR0gBIIBFDCCARAwggEMBgkqhkiG92NkBQEwgf4wgcMGCY2QGAQIBAf8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQCJw3MoEbhJNVyc1PFG6FtY7QZAy+gmqRz9YiwnFh3y5Qj5lnC2n0WdG8SrlZA+TKQgfwRZNEB6ZIfDZOJAFsqpBMAauC1V0CDzP8UWBDfluoVCU89Ns5juag8ffk/ulEQfEN1NakgiSwihy+QEmd2PWBTn4dfGVSV9mYRjPppFdM6kik1WLgMDZfLRmNzZ0MzMZMAPy8gdMmQiM7uBY1v+EnUXfyjKnK7Y28AB9c6oQHPoTGmVQxZjJgkejyOlBPWwVPbNvvzNRPuBaHI8muX2HzjsA9SJowEBXKICinqLSFZ8NDQVBrw2fgDs5MD5vaDHXtrz9t6Ahw6/7nUB240U</data>
        <data>***LDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwOTI1MDIxMzA4WhcNMTkwOTI1MDIxMzA4WjCBrzEaMBgGCgmSJomT8ixkAQEMCjIzVDNTWlo0WjQxMjAwBgNVBAMMKWlQaG9uZSBEZXZlbG9wZXI6IOS9s+a7qCDnjosgKDN1UdDgQWBBT7im/bw3RlTv0soM/RVB2mmh9e4zAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBACErmsYfmt/qn5yj86poEkDsDWhznabHVn1CJprtzyHbXNcbKJE1pY99ACzSUVW9iGaxXJ9m5dWmZsd+2gxOBthFDq4mSpU50OHQgg9AjjugvsQ+OH1r1qgqcJMPdLN4stJtkAC9Mb/rt3AYA5eEdHOXbhrsE3TXWmWfJzYS9PFyarGcJ9xFAWg76jTtFA6nlzYtl/YyMDS6Z075oMzKG/pRfCI13P4AqRKdx/DBtz4x0Wv59LVMVrXa4bfePLKMBJrBFdiiyCy4k4BIx4weG/Y/8OsEkmWkN0fDWmi4MZjy3I+FCNkv9tUzI/vRvDEiNR7qo5rGRKnAi+X1QbdLYcU=</data>
        <data>***o0WjQxMjAwBgNVBAMMKWlQaG9uZSBEZXZlbG9wZXI6IOS9s+a7qCDnjosgKDNYTDJNRFdWOUcpMRMwEQYDVQQLDApaRVdKTUhHQ0RCMTswOQYDVQQKDDJTaGFuZ2hhaSBSaXNlbiBFbGVjdHJpYyBQb3dlciBEZXZlbG9wbWVudCBDby4sTHRkLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC35nKt/AoSiANJn9e9H96rol/85zSEAjAAMB8GA1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MD8GCCsGAQUFBwEBBDMwMTAvBggr1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBSIeBiIaX4EyW39H2laObRLnSyWVjAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQCyETSZ/FOr8EBZBVLmMGXz03x6f2Hpd7QsmoJJM5+6hHu4qgstgXNg0RRsa0B4jScKTMlRxmdZuLjm3plaX+P+yo0ylAnvGWm1sx9mxPTgrDbUg7Rg0n1bhrBtkX47+r8SUz4+E6dHnqZ7x48hZlhv6SFkj4PQ/apeAvITvnLeq7bj586gkpwS30bjmrsqSO8aEnysvyxq6Xx3+seH9Uihmjb7XdnV25mKfbf5ms6sm+HrN6ifrDb0LePX8YAsSH4=</data>
    </array>


    <key>Entitlements</key>      // 权限
    <dict>
        <key>keychain-access-groups</key>
        <array>
            <string> *** .*</string>        
        </array>
        <key>get-task-allow</key>    // APP是否允许调试
        <true/>
        <key>application-identifier</key>    // appID
        <string> *** </string>
        <key>com.apple.developer.associated-domains</key>
        <string>*</string>
        <key>com.apple.developer.team-identifier</key>
        <string> *** </string>
        <key>aps-environment</key>
        <string>development</string>

    </dict>
    <key>ExpirationDate</key>    // 过期时间
    <date>2020-03-05T08:54:06Z</date>
    <key>Name</key>
    <string>iOS Team Provisioning Profile: *** </string>
    <key>ProvisionedDevices</key>    // 设备列表
    <array>
        <string>476c21e91700a0605a11a***3de7705a</string>
        <string>98a1263783fb5538ec292f0***9d05690ffb</string>
        <string>bc9144d7496e5337e1f***cb653dc42e</string>
        <string>254fbcad0126f989b8980***d1dd8169b6ca</string>
        <string>349f7aeb300473cc30c28***025d</string>
    </array>
    <key>TeamIdentifier</key>
    <array>
        <string> *** </string>
    </array>
    <key>TeamName</key>
    <string> *** Co.,Ltd.</string>
    <key>TimeToLive</key>
    <integer>365</integer>
    <key>UUID</key>    // 描述文件的UUID
    <string> *** </string>
    <key>Version</key>
    <integer>1</integer>
</dict>

双层代码签名

  • 请求证书
    开发过程中,首先Mac电脑(比如Xcode)会自动生成一对公私钥
公私钥

图中的证书就是公钥M,专用密钥就是私钥M(也就是我们导出的P12文件)

用一个CSR文件(就是在钥匙串访问中,证书助理,从证书颁发机构中获取的)向苹果申请一个证书,这个CSR文件主要包含了一个公钥文件,还有一些信息,比如邮箱、名字、签名信息、Hash值等等,苹果收到请求后,会用私钥A将公钥M进行签名,以供苹果设备进行验证(用公钥A进行验证)。苹果服务器将公钥M和签名信息打包成证书,并把appID、证书、设备IDs、权限文件等放入描述文件一并返回给Mac电脑,以备Mac电脑用这个描述文件中的证书到iOS设备去验证。

请求证书
  • 生成IPA文件,发送到iOS设备上
    iOS设备上的APP其实都是文件夹,最重要的是可执行文件MachO和framework,APP签名也就是对它俩进行签名,通过Mac电脑的私钥M对文件进行签名,把这个签名和从苹果申请的描述文件一并放入到APP中。当安装APP时,iOS设备用公钥A来解析描述文件中的证书进行验证证书的有效性,通过之后将证书中的公钥M拿出来,再去验证APP签名的有效性,这样就可以验证当前APP是否是苹果官方允许的。
双层代码签名

在开发阶段,我们需要频繁的改动程序跑真机,苹果不需要关心这些,所以iOS设备没有对APP的更改进行验证,只是验证证书(公钥M是不是合法的,APP签名的有效性)。这样解决了安装问题,但是如果这样的话,可以在任何一部iOS设备上安装APP,苹果防止开发者滥用,又加了两个限制:

  1. 要在苹果后台注册过的设备才可以安装
  2. 签名只能针对具体的某一个APP进行签名

关于APP签名

在开发中,编译一个APP后,用本地的私钥M对APP进行签名,同时把从苹果服务器得到的Provisioning Profile文件打包进APP中,文件名为embedded.mobileprovision,把APP安装到iOS设备后,系统进行验证。

查看资源文件签名

查看APP的包内容,里面会有_CodeSignature文件夹(里面的就是资源文件的签名),还有个可执行文件,可以用MachO查看,里面的Code signature就是应用签名。

该文章为记录本人的学习路程,希望能够帮助大家,也欢迎大家点赞留言交流!!!文章地址:https://www.jianshu.com/p/4307de384a50

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容

  • 一 概述 之前我在做iOS项目开发时,由于采用的是自己的开发者账号,在Xcode的General配置中勾选上Aut...
    YesWeCan阅读 1,874评论 0 14
  • iOS 签名机制挺复杂,各种证书,Provisioning Profile,entitlements,Certif...
    不忘初心1990阅读 352评论 0 1
  • iOS 签名机制挺复杂,各种证书,Provisioning Profile,entitlements,Certif...
    iYeso阅读 902评论 0 3
  • 转自 bang' blog 有改动。 iOS 签名机制挺复杂,各种证书,Provisioning Profile...
    就叫yang阅读 771评论 0 2
  • 不知道大家有没有人和我一样,梦境里都是像侦探剧一样,有连贯的剧情,各种各样的人设。有时候是浪漫的偶像剧,有时候是紧...
    严啊蝶阅读 191评论 0 0