bsp; }
26
27 break;
28 case SOCK_CLOSE_WAIT:
29 disconnect(s);
30 querry_flag=0;
31 break;
32 case SOCK_CLOSED:
33 querry_flag=0;
34 socket(s,Sn_MR_TCP,localport,Sn_MR_ND);
35 break;
36 }
37 }
由于苹果的AirPlay协议为了防止其他未经苹果允许的设备的接入,对传输的数据用非对称性RSA加密算法进行加密,非对称性的意思就是加密和解密用的不是同一份密钥,RSA加密算法的密钥分为公钥和私钥,两者内容不同,用途也不同。公钥用于加密,一般交给客户端使用;私钥用于解密,一般由服务器管理。iPhone中存有公钥用来对iPhone输出的数据流进行加密,接收端设备利用私钥对接收的数据(音频)流进行解密。W5500EVB是作为服务器接收数据所以我们只需要知道私钥就可以解析数据,我们可以直接百度网上已有大神破译出的私钥。RSA加密算法的实现可以参考开源项目https://github.com/juhovh/shairplay工程中的RSA加密解密相关函数。
iPhone会先发送OPTIONS请求来确定W5500EVB支持的方法,W5500EVB回复支持的全部方法包含ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER等,方法具体含义可参考RTSP协议相关文档。
iphone OPTIONS 请求报文:
OPTIONS * RTSP/1.0
CSeq: 0
DACP-ID: 4CB06073C86450D8
Active-Remote: 2937221397
User-Agent: AirPlay/373.9.1
图1-5 OPTIONS请求报文
W5500EVB响应报文:
RTSP/1.0 200 OK
CSeq: 0
Apple-Jack-Status: connected; type=analog
Public:ANNOUNCE,SETUP,RECORD,PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER,SET_PARAMETER
图1-6 OPTIONS响应报文
iphone收到W5500EVB的响应后,会向W5500EVB发送包含Apple-Challenge的OPTIONS数据包,Apple-Challenge后的参数是随机生成且经过了RSA算法加密,W550EVB要将Apple-Challenge中的参数先进行base64解码,解码后的数据尾部添加W5500EVB的IP地址和MAC地址然后通过RSA私钥加密后用base64编码,W5500EVB将加密处理后的数据作为Apple-Response的参数发送给iPhone,iPhone该数据进行验证,数据正确则进行下一步,数据不正确则断开连接。下图为包含Apple-Challenge的OPTIONS 数据包:
OPTIONS * RTSP/1.0
Apple-Challenge: UJPWMzMloBFr98cQQHX3OQ==
CSeq: 2
DACP-ID: 4CB06073C86450D8
Active-Remote: 2937221397
User-Agent: AirPlay/373.9.1
图1-7 Apple-Challenge报文
接收到OPTIONS数据包后,截取Apple-Challenge相关数据,并进行解密代码如下:
1if(strstr(rcv_buffer,"Apple-Challenge:")!=NULL)
2 {
3 rsakey_t *rsakey;
4 rsakey = rsakey_init_pem(pemstr);
5 if (!rsakey) {
6 printf("Initializing RSA failed\n");
7 return;
8 }
9 memset(response,0x00,1024);
10 /*获取Apple-Challenge参数*/
11 mid(rcv_buffer,"Apple-Challenge: ","\r\n",CHALLENGE);
12 /*获取加密Apple-Response*/
13 rsakey_sign(rsakey, response, sizeof(response), CHALLENGE,ipaddr, sizeof(ipaddr), hwaddr, sizeof(hwaddr));
14 mid(rcv_buffer,"CSeq: ","\r\n",CHALLENGE);
15 sprintf(send_buffer,"RTSP/1.0 200 OK\r\nCSeq: %s\r\nApple-Jack-Status:connected; type=analog\r\nApple-Response: %s\r\nPublic: ANNOUNCE, SETUP,RECORD