美文网首页
IOS 超级签名实现 (linux 版本)

IOS 超级签名实现 (linux 版本)

作者: pokerface_max | 来源:发表于2020-06-29 12:07 被阅读0次

    前言

    签名原理其实就一句话,使用了苹果提供给开发者的Ad-Hoc分发通道,把安装设备当做开发设备进行分发。

    既然签名用是 Ad-Hoc ,那么 Ad-Hoc 所具有的优劣势也一并继承了下来:

    优势:

    直接分发,安装即可运行,不需要用户做企业证书的信任操作
    目前稳定,不会有证书吊销导致的业务风险(后续苹果政策风险非常高)
    缺点:

    单开发者账号的iPhone设备数量只有100个,导致分发成本非常高(99美元/1年/100个设备)
    开发者账号需要预先写入安装设备的UDID,在工具链不通的情况下,获取用户的UDID相对困难和繁琐,而且手动写入UDID不存在商用可行性,当然目前这个缺点被解决了

    获取用户设备的UUID

    过程参考
    https://www.jianshu.com/p/fc0c2b24ac74

    登录apple账号注册设备,生成新的mobileprovision

    注意保存以下几个文件:

    • 生成的certificateSignRequest, certificateSignRequestPrivateKey
    • 生成的certificate文件
    • 生成的mobileprovision 文件

    Apple Developer Center 自动化工具

    可以使用fastlane-Spaceship来完成命令行登录appstore, 创建appid,创建certificate,更新profile等一系列操作,完美支持centos7+ 服务器
    具体api 可参考 Spaceship Portal Api
    然后编写ruby脚本来实现命令行完成profile更新, 脚本如下:

    #
    # 一键注册设备生成签名文件
    # 使用ruby generate_provision.rb 来执行 需要安装ruby 命令
    #
    #
    require "spaceship"
    
    class PortalHandle
        # 初始化参数
        def initialize(appid,username,password,teamId,uuid,csrFile,provisionFile,crtFile)
            @appid = appid                                   # 新的appid
            @username = username                     # apple账号
            @password = password                      # apple账号密码
            @teamId = teamId                              # apple 团队id
            @registerUuid = uuid                          # 需要注册的设备uuid
            @csrFile = csrFile                                # 生成的csr文件,需要和签名用的key 成对
            @provisionFile = provisionFile             # 保存新profile路径
            @certificateFile = crtFile                      # 保存新certificate路径
        end
    
        #   登录苹果账号
        def login()
            Spaceship::Portal.login(@username,@password)
            Spaceship.client.team_id = @teamId
            say 'Login Success!'
        end
    
    
        # 注册新设备到此账号
        def registerDevice()
            current_device = Spaceship::Portal.device.find_by_udid(@registerUuid, include_disabled: true)
            if current_device == nil then
                Spaceship::Portal.device.create!(name: @registerUuid, udid: @registerUuid)
                say 'Register device into account'
            else
                current_device.enable!
                say 'Device exist in account. enable it'
            end
        end
    
        # 查找或者创建appid
        def createAppid()
            app = Spaceship::Portal.app.find(@appid)
            if app == nil then
                app = Spaceship::Portal.app.create!(bundle_id: @appid, name: "fastlane App")
                say 'Appid not exist generate...'
            end
            app.update_service(Spaceship::Portal.app_service.push_notification.on)
        end
    
        # 创建证书  如果存在则不创建
        def createCertificate()
            prod_certs = Spaceship::Portal.certificate.apple_distribution.all
            if 0 == prod_certs.length then
                # Create a new certificate signing request
                # csr, pkey = Spaceship::Portal.certificate.create_certificate_signing_request
                # Use the signing request to create a new distribution certificate
                # Spaceship::Portal.certificate.apple_distribution.create!(csr: csr)
                # csrFile = File.new('ios.certificateSignRequest','w')
                # csrFile.syswrite(csr)
                # csrFile.close
                # say 'Download csr Success...!'
                # keyFile = File.new('ios.key','w')
                # keyFile.syswrite(pkey)
                # keyFile.close
                # say 'Download privateKey success...!'
                # File.write('ios_producttion.cer',Spaceship::Portal.certificate.apple_distribution.all.first.download)
                # 从文件中读取csr 由于多个账号共享同一个csr和key
                csr = File.read(@csrFile)
                Spaceship::Portal.certificate.apple_distribution.create!(csr: csr)
            end
            # 下载certificate
            File.write(@certificateFile,Spaceship::Portal.certificate.apple_distribution.all.first.download)
            # 返回证书
            return  Spaceship::Portal.certificate.apple_distribution.all.first
        end
    
        # 生成ad_hoc profile
        def createAdhocProfile()
            # 创建并获得线上证书
            cert = createCertificate()
            # 获取
            # 创建最新的证书
            matching_profiles = Spaceship::Portal.provisioning_profile.ad_hoc.find_by_bundle_id(bundle_id: @appid)
            profile = nil
            if 0 == matching_profiles.length then
                profile = Spaceship::Portal.provisioning_profile.ad_hoc.create!(bundle_id: @appid,
                                                          certificate: cert,
                                                                 name: 'profile_production_adhoc'+@appid)
            else
                devices = Spaceship::Portal.device.all
                profile = matching_profiles.first
                profile.devices = devices
                profile.update!
            end
            profile = Spaceship::Portal.provisioning_profile.ad_hoc.find_by_bundle_id(bundle_id: @appid).first
            provisionFileName = @provisionFile
            File.write(provisionFileName, profile.download)
        end
    end
    
        appid                     = ARGV[0]
        username             = ARGV[1]
        password             = ARGV[2]
        teamId                 = ARGV[3]
        uuid                     = ARGV[4]
        csrFile                 = ARGV[5]
        provisionFile          = ARGV[6]
        certificateFile         = ARGV[7]
    
        handler = PortalHandle.new(appid,username,password,teamId,uuid,csrFile,provisionFile,certificateFile)
        # 登录
        handler.login()
        # 注册这个设备
        handler.registerDevice()
        # 查找或者创建appid
        handler.createAppid()
        # 创建证书
        handler.createAdhocProfile()
    

    参考文章

    IOS 超级签名原理

    相关文章

      网友评论

          本文标题:IOS 超级签名实现 (linux 版本)

          本文链接:https://www.haomeiwen.com/subject/cyoqfktx.html