iOS MDM开发

前言

关于MDM,谷歌搜遍了也搜不出多少资料,甚至有的资料会误导小伙伴们。我实现了MDM并且整理了一份详细的文档,供大家参考,表述有误之处请见谅并及时在评论里告知我修改。

转载请注明出处:http://www.jianshu.com/p/2173e0df5761

参考链接:

http://www.jianshu.com/p/fef831dfe12c
http://blog.csdn.net/column/details/ios-mdm.html
http://blog.csdn.net/kmyhy/article/details/23171017
http://www.mbaike.net/mdm/24.html

参考文档:(链接我就不放了,大家自己找吧,找不到也没关系)

InsideAppleMDM.pdf
CommandReference.pdf

正文

以下“服务器”都是指MDM服务器,而且必须是https服务器

MDM服务器与APNS、设备的大致通信流程

1、生成并配置好mobileconfig文件,放在服务器上
2、设备访问服务器上的mobileconfig文件,点击注册以及信任按钮后,设备主动发起请求mobileconfig里的checkin URL。设备首先发起Authenticate,服务端录入数据后返回空plist,接着设备发起TokenUpdate,服务端录入数据后返回空plist。
3、以锁屏为例,服务端将锁屏命令发给APNS,当苹果的 APNS 服务器通知设备访问 MDM 服务器时,设备首先会向服务器(mobileconfig里的server URL)发送一个Status:Idle 消息(如果设备空闲),表示 MDM 服务器现在可以把指令取给它执行。服务器组装成 Plist 文件响应给它。
4、设备执行完命令,会再次向 server 发送 Acknowledged 消息,告诉服务器执行状态,然后服务器简单回复一个空响应(即200),并关闭连接。

以下是MDM vendor和customer申请制作

MDM Vendor申请(必须是企业版开发者账号)

1、前往https://developer.apple.com/contact/submit.php给苹果留言,说明你要申请MDM以及申请理由。
2、若干天后,苹果会回复一封邮件,让你打电话给他们,并且给你提供了一个case number。打电话时必须要报开发者证书代理人姓名,以及case number,才会给你开放。
3、客服会帮你开通,成功后她会发给你一封邮件,带有MDM的详细介绍链接,然后在developer center里,创建生产证书那边会新增一个MDM CSR选项,表示申请成功。

MDM 证书制作和申请

(建议在Mac电脑下操作,如果是Windows则要先安装openssl和python,(Mac自带了它们),而且命令可能有区别,建议所有文件都统一放到一个文件夹下!所有命令都在该文件夹下操作!以下步骤需要输入密码,请务必记住密码,建议统一所有密码!)
创建MDM Vendor CSR,并上传到developer center创建MDM证书

1、钥匙串->钥匙串访问->证书助理->从证书颁发机构请求证书->填写开发者账号的Apple ID(例如:myCompany@qq.com)、常用名称(公司名称+MDM,例如:MyCompany MDM)、选择存储到磁盘,生成CertificateSigningRequest.certSigningRequest,保存.
2、前往developer center,创建证书->MDM CSR,上传刚才创建的CertificateSigningRequest.certSigningRequest,生成mdm.cer,下载下来,双击安装到钥匙串(登录->证书)。

创建MDM推送CSR

再次打开钥匙串->钥匙串访问->证书助理->从证书颁发机构请求证书->填写开发者账号的Apple ID(例如:myCompany@qq.com)、常用名称(公司名称+MDMPush,例如:MyCompany MDMPush)、选择存储到磁盘,生成mdm_push.certSigningRequest,保存.

导出私钥并制作证书
1、点击展开mdm.cer安装到钥匙串的证书,导出私钥为private.p12,保存。
2、将私钥private.p12提取出私钥
openssl pkcs12 -in private.p12 -nocerts -out key.pem
3、提取证书
openssl pkcs12 -in private.p12 -clcerts -nokeys -out cert.pem
4、将证书转换成DES格式
openssl x509 -in cert.pem -inform PEM -out mdm.cer -outform DES
5、去掉private key密码
openssl rsa -in key.pem -out private.key
使用mdm_vendor_sign工具制作CSR
1、下载mdm_vendor_sign(https://github.com/grinich/mdmvendorsign)
2、运行python mdm_vendor_sign.py --key private.key --csr mdm_push.certSigningRequest --mdm mdm.cer --out applepush.csr
3、运行成功后,会提示 Go upload file 'applepush.csr' to identity.apple.com/pushcert !,否则为不成功。
4、如果不成功,则需要做一些改动:
首先手动下载AppleWWDRCA.cer证书到此目录 ([https://developer.apple.com/certificationauthority/AppleWWDRCA.cer](https://developer.apple.com/certificationauthority/AppleWWDRCA.cer))
修改mdm_vendor_sign.py 代码128行为:intermediate_cer = open(‘AppleWWDRCA.cer','r').read()
再次运行即可。
从Apple获取推送证书
1、将上一步生成的applepush.csr上传到[https://identity.apple.com/pushcert](https://identity.apple.com/pushcert)
2、下载推送证书,安装到钥匙串,显示 APSP:xxxxxx
3、导出该推送证书为p12,给服务端使用。

MDM Customer

(Vendor生成后的证书是通用的,而接下来的customer则是和服务器地址有关,所以更换服务器地址时则要重新完成以下步骤)
生成配置mobileconfig文件

1、下载IPCU(iPhone Configuration Utility,网上搜一下就有下载地址,如果下载下来的发现无法完成以下步骤,说明你下错了,再去找找)(网上说苹果已废弃它,实际上废弃的仅仅只是它的主要功能而已,它仍然能够用于配置生成mobileconfig文件)。
2、打开IPCU,选择配置描述文件->新建,即新建一个配置描述文件
3、点击通用,填写名称、标识符(该描述文件的唯一标识,例如:com.公司名.mdm)、机构、描述、安全性
4、点击凭证-> + ,添加服务器的ca根证书,再点击+,添加用服务器证书和key生成的p12文件,填写密码。(如果不清楚https服务器证书如何生成,请参考底下的“https生成自签名证书”)
5、点击移动设备管理,填写服务器URL(server)、登记URL(checkin),打开钥匙串,找到vendor步骤里安装的推送证书(APSP:xxxxxx),双击,复制用户id,粘贴到主题。 身份选择在凭证里添加的p12,“移除时检查”勾选上时,在移除描述文件时会向MDM服务器发起checkout请求,建议勾选,其他的选项根据需求去勾选,最后一项使用开发APNS服务器不要勾选!
6、导出->安全性选择“无”,导出为mobileconfig文件。
7、将mobileconfig放在服务器上,提供下载接口,设备用safari访问该接口,即可自动打开设置进入描述文件的安装界面,点击注册->注册->信任,如果安装成功,到此步骤即完成了证书的申请配置以及描述文件的配置安装,接下来就是MDM服务器的搭建和调试与设备的通信了。
8、设备与服务端的请求都是PUT请求,具体可通过抓包查看,服务端的代码可参考https://github.com/zuoyy/IOS-MDM-Server

实现了功能还不够,仍然有几个问题需要解决:

1、客户端如何检查是否已安装了描述文件?(即是否可控?):

解决方案:目前我能想到的办法是通过判断当前服务器的https证书是否已受信任来解决,因为描述文件携带的凭证含有服务器的https证书,如果判断的结果为已信任,则说明已安装了该描述文件,可接受控制;否则就是没有安装了。
判断的代码如下:
<pre>
<code>

+ (BOOL)IsCertificatesTrusted:(NSArray<NSData *> *)certDatas {
    
    if (certDatas.count == 0) {
        return NO;
    }
    
    CFMutableArrayRef certs = CFArrayCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeArrayCallBacks);
    
    for (NSData *certData in certDatas) {
        SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData);
        if (!cert) {
            continue;
        }
        
        CFArrayAppendValue(certs, cert);
        CFRelease(cert);
    }
    
    SecPolicyRef policy = SecPolicyCreateBasicX509();
    SecTrustRef trust;
    
    OSStatus err = SecTrustCreateWithCertificates(certs, policy, &trust);
    CFRelease(certs);
    CFRelease(policy);
    if (!trust) {
        return NO;
    }
    if (err != errSecSuccess) {
        CFRelease(trust);
        return NO;
    }
    
    SecTrustResultType trustResult = -1;
    err = SecTrustEvaluate(trust, &trustResult);
    CFRelease(trust);
    if (err != errSecSuccess) {
        return NO;
    }
    
    if(trustResult == kSecTrustResultUnspecified) {
        return YES;
    } else {
        return NO;
    }
}

</code>
</pre>

2、断网情况下移除描述文件,服务器如何更新数据库?

如果你在配置mobileconfig时有勾选上“移除时检查”,那么在联网情况下如果移除描述文件,设备会主动发起checkout请求告诉服务器设备已退出控制,服务器可更新数据库。
但是断网的情况下怎么办?
虽然第一个问题解决了客户端判断设备是否已安装了描述文件,但是设备在checkin提交的设备唯一标识是UDID,而IOS是不允许用代码获取设备的UDID的,也就是说,客户端无法告诉服务器设备当前到底可不可控。
在谷歌上搜索到了这么一篇文章:http://www.mbaike.net/mdm/24.html
从中想到的方案是:
服务端可通过定期主动发起查询命令来判断当前设备是否可控。
该方案理论上可行,但不知是否会引发其他问题,待验证。如果有大神有完美的解决方案,请带我。

https生成自签名证书

一、创建CA证书
1、创建一个私钥,命名为rootCA.key
openssl genrsa -out rootCA.key 2048
2、创建根证书,命名为rootCA.cer,(common name填写服务器地址)
openssl req -x509 -new -key rootCA.key -out rootCA.cer -days 730
######二、制作自签名 SSL 证书
1、创建一个私钥,命名为server.key
openssl genrsa -out server.key 2048
2、创建CSR
openssl req -new -out server.req -key server.key -subj /CN=127.0.0.1/CN=填写服务器地址/CN=localhost
3、用CSR创建SSL证书
openssl x509 -req -in server.req -out server.cer -CAkey rootCA.key -CA rootCA.cer -days 36500 -CAcreateserial -CAserial server.serial
4、将 .key 和 .cer 文件导出为 .p12 证书
openssl pkcs12 -export -in server.cer -inkey server.key -out server.p12 -name "server"
5、将 .p12 文件导入到 Java keystore 中
keytool -importkeystore -v -srckeystore server.p12 -srcstoretype pkcs12 -srcstorepass 密码 -destkeystore server.keystore -deststoretype jks -deststorepass 密码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容