ios ipa ota签名服务器

使用的是https://github.com/apperian/isign这个二次修改过的库,不能使用https://github.com/sauce-archives/isign,原来的库作者早就不更新,使用的话,虽然能安装,但是打开app的时候会提示无法验证。

使用

克隆下来

git clone https://github.com/apperian/isign.git

安装

cd isign
python setup.py build
python setup.py install

运行

isign

个人证书打包测试

p12证书转换

openssl pkcs12 -in ./证书.p12 -out /tmp/cert.pem -clcerts -nokeys
openssl pkcs12 -in ./证书.p12 -out /tmp/key.pem -nocerts -nodes

对ipa进行重签名

isign -c /tmp/cert.pem -k /tmp/key.pem -p phone.mobileprovision -o 签名成功.ipa ./未签名.ipa

生成plist xml文件用于在线安装ipa

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>items</key> <array> <dict> <key>assets</key> <array> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <string>https://demo.ipa</string> </dict> <dict> <key>kind</key> <string>display-image</string> <key>needs-shine</key> <true/> <key>url</key> <string>https://demo.com/icons/esign.png</string> </dict> </array> <key>metadata</key> <dict> <key>bundle-identifier</key> <string>p3.xyz.yyyue.esign</string> <key>bundle-version</key> <string>4.8.1</string> <key>kind</key> <string>software</string> <key>title</key> <string>轻松签</string> </dict> </dict> </array> </dict> </plist>

plist koa代码

router.get('/install/ipa.plist', async (ctx, next) => {
    ctx.type = 'application/xml'
    ctx.body = `<?xml>.....</plist>`
    }
)

ipa 文件下载 koa代码

router.get('/file/download//install.ipa', async (ctx, next) => {
    let ipa_path = path.resolve('files', `已签名.ipa`)
    if(!fs.existsSync(ipa_path)){
        ctx.body = {
            code: -1,
            msg: '文件不存在'
        }
        return
    }
    let file = fs.readFileSync(ipa_path)
    ctx.type = 'application/octet-stream'
    ctx.body = file
})

ipa文件上传签名koa代码

router.post('/file/upload', multiple(), async (ctx, next) => {
    const files = ctx.req.files
    let p12_path = files.p12.path
    let password = ctx.req.body.password
    let uuid = uuidv4().replace(/-/g, '')
    let date = moment().format('YYYY-MM-DD')
    let hour = moment().format('HH')
    let esign_path = path.resolve(`ipas`, `easign_4.8.1.ipa`)
    let date_path = path.resolve(`files`, `${date}/${hour}/${uuid}`)
    if (!fs.existsSync(date_path)) {
        fs.mkdirSync(date_path, {recursive: true})
    }
    let certificate_path = path.resolve(date_path, 'cert.pem')
    let key_path = path.resolve(date_path, 'key.pem')
    let p12cert_result = shell.exec(`openssl pkcs12 -passin pass:${password} -in ${p12_path} -out ${certificate_path} -clcerts -nokeys`, {silent: true})
    let p12key_result = shell.exec(`openssl pkcs12 -passin pass:${password} -in ${p12_path} -out ${key_path} -nocerts -nodes`, {silent: true})
    if (p12cert_result.stderr.includes('invalid password') || p12key_result.stderr.includes('invalid password')) {
        ctx.body = {
            code: -1,
            msg: '证书密码错误'
        }
        return
    }
    let sign_result = shell.exec(`isign -c ${certificate_path} -k ${key_path} -p ${files.mp.path} -o ${date_path}/esign.ipa ${esign_path}`, {silent: true})
    if (!sign_result.stderr.includes('archived IpaArchive to')) {
        ctx.body = {
            code: -1,
            msg: '签名异常'
        }
    }
    ctx.body = {
        code: 0,
        data: {
            plist: `itms-services://?action=download-manifest&url=https://demo.com/sign/install/ipa.plist`
        }
    }
})

猜你喜欢

转载自blog.csdn.net/dounine/article/details/130036734