1. 声纹识别
声纹识别(Voiceprint Recognize),是一项提取说话人声音特征和说话内容信息,自动核验说话人身份的技术。MSC SDK 声纹识别(IdentityVerfier)的使用包括注册(训练)、验证和模型操作。类似于一个网站的用户登录一样,用户必须先注册,才能登录(验证),在用户忘记密码时,可以提供重设密码的操作(模型操作)。
声纹使用过程的主要参数有:
- 用户ID(AUTH_ID):标识每个使用声纹功能的终端用户的唯一ID注:长度为6-18个字符(由英文字母、数字、下划线组成,不能以数字开头),不支持中文字符。
- 业务类型(MFV_SST):用来标识本次会话是注册还是验证
- 密码类型(MFV_PWDT)
- 密码(MFV_PWD):进行声纹注册(训练)时传入的密码
- 模型操作命令(CMD):进行声纹模型查询和删除
- 注册次数(MFV_RGN):声纹训练次数
不同 APPID 的用户 ID 相互独立,即不同的 APPID 可以用相同的用户 ID——他们注册的模型也相互独立。如果您的项目使用了多个appid(例如分Android和iOS两个app版本),需要多个appid的用户id数据打通,可以通过文章末尾的技术支持联系方式与我们联系。
1.1. 声纹注册
目前 MSC SDK 支持两种类型的声纹密码:数字密码和文本密码。文本密码的效果在优化中,建议使用数字密码。密码类型的取值说明如下表所示:
取值 | 说明 |
---|---|
1 | 文本密码。用户通过读出指定的文本内容来进行声纹注册和验证,现阶段不支持。 |
2 | 自由说。用户通过录入一段任意20s以上音频进行注册,验证时录入任意5s以上音频即可完成验证,现阶段不支持。 |
3 | 数字密码。从云端拉取若干组特定的数字串(默认有5组,每组8位数字),用户依次读出这5组数字进行注册,在验证过程中会生成一串特定的数字,用户通过读出这串数字进行验证。 |
注册时使用的密码通过调用 getPasswordList 方法获取:
// 设置会话场景
mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
// 子业务执行参数,若无可以传空字符传
StringBuffer params = new StringBuffer();
// 设置模型操作的密码类型
params.append("pwdt=" + mPwdType + ",");
// 执行密码下载操作
mIdVerifier.execute("ivp", "download", params.toString(), mDownloadPwdListener);
通过 mDownloadPwdListener 回调中获取的密码,进行声纹注册。
// 设置会话场景
mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
// 设置会话类型
mIdVerifier.setParameter(SpeechConstant.MFV_SST, "enroll");
// 设置训练次数(可以不做设置,sdk中默认设置为5次)
mIdVerifier.setParameter(SpeechConstant.MFV_RGN, "5");
// 用户id
mIdVerifier.setParameter(SpeechConstant.AUTH_ID, authid);
// 设置监听器,开始会话
mIdVerifier.startWorking(mEnrollListener);
应用通过 mEnrollListener的 onResult 方法来处理注册结果。在结果result中携带了一个返回码(0表示成功,-1为失败)和错误码,用来判别注册是否成功以及出错原因,错误码的含义如下:
错误码 | 数值 | 说明 |
---|---|---|
MSS_ERROR_IVP_GENERAL | 11600 | 正常,请继续传音频 |
MSS_ERROR_IVP_EXTRA_RGN_SOPPORT | 11601 | rgn超过最大支持次数9 |
MSS_ERROR_IVP_TRUNCATED | 11602 | 音频波形幅度太大,超出系统范围,发生截幅 |
MSS_ERROR_IVP_MUCH_NOISE | 11603 | 太多噪音 |
MSS_ERROR_IVP_TOO_LOW | 11604 | 声音太小 |
MSS_ERROR_IVP_ZERO_AUDIO | 11605 | 没检测到音频 |
MSS_ERROR_IVP_UTTER_TOO_SHORT | 11606 | 音频太短 |
MSS_ERROR_IVP_TEXT_NOT_MATCH | 11607 | 音频内容与给定文本不一致 |
结果中包含的字段以及各字段的含义见附录。
1.2. 声纹验证
声纹验证过程与声纹注册类似,不同之处仅在于MFV_SST需要设置为“verify”,且不用设置 MFV_RGN 参数,并且,在数字密码类型时,密码通过 VerifierUtil.generateNumberPassword 生成。其他参数的设置、验证结果的处理过程完全可参考上一节。
另外,为了达到较好的效果,请在声纹注册与验证过程中尽量与麦克风保持同样的距离(建议的最佳距离是15厘米左右)。如果距离差距较大的话,可能会对验证通过率产生较大影响。
1.3. 模型操作
声纹注册成功后,在语音云端上会生成一个对应的模型来存储声纹信息,声纹模型的操作即对模型进行查询和删除。
// 设置会话场景
mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
// 用户id
mIdVerifier.setParameter(SpeechConstant.AUTH_ID, authid);
// 子业务执行参数,若无可以传空字符传
StringBuffer params3 = new StringBuffer();
// 设置模型操作的密码类型
params3.append("pwdt=" + mPwdType + ",");
// 执行模型操作,cmd 取值为"query","delete",分别表示查询和删除
mIdVerifier.execute("ivp", cmd, params3.toString(), mModelListener);
1.4. 安全性问题
从上文的3个小节可以看到,对应用来说,操作声纹都是很简单直接的。因此,有些安全性也是应用应该考虑的:
更新模型:应用在给用户更新声纹模型等操作时,为了安全性,应该考虑必要的验证,如,必须先通过声纹密码或应用登录密码验证,才能进行下一步更新声纹模型(重新注册)——类似修改密码时,必须先进行安全性验证一样。
APPID:从前面的特征可以看到,如果 APPID 与 libmsc.so 泄漏后,使用这个 APPID 和 libmsc.so 就可以绕过应用层的安全验证,操作该 APPID 的所有用户ID的模型。所以,应用的 APPID 须保证不泄漏给他人——如不要以明文方式在代码中以字符串保存;在论坛发帖求助时,不要在所有浏览者都可见的正文中带 APPID 内容等。
用户ID:SDK 对通过验证 APPID 的应用,只要指定用户 ID 就可以进行更新模型操作(先删除,再注册,或注册时指定替换)。所以,应用应当考虑用户可能会恶意指定他人的用户 ID,进行注册或验证的情况。应用可以在展示给用户的账号和用来注册 MSC SDK 声纹的用户 ID 间,做一层映射,使用户无法直接看到或猜测到实际用于 MSC SDK 声纹时的用户 ID 值;同时,应用在用户操作声纹密码的页面中,应尽可能的把账号设置为只读——避免恶意修改他人账号声纹密码的情况。
验证密码:因为人的声音是可以录制下来的,当验证的密码固定不变时,用户的声音就比较大可能被别人录制下来,然后再次用来验证——在密码相同时。所以,用来验证的密码时,每次都不一样时,安全性可以更大的提搞——随机数字密码,比固定文本密码更安全。同时,也应该提醒用户,在注意声音的泄漏或被盗用——如留意不要随意输入银行卡密码一样。
1:N检索:鉴别与验证的过程相似,不过鉴别需要设置组 ID,以指定要鉴别的组。其参数设置如下:
// 设置业务场景
mIdVerifier.setParameter( SpeechConstant.MFV_SCENES, scene );
// 设置业务类型:鉴别(identify)
mIdVerifier.setParameter( SpeechConstant.MFV_SST, "identify" );
// 设置监听器,开始会话
mIdVerifier.startWorking( listener );
// 指定组id,最相似结果数
String params = "group_id="+groudID
while( !isDataFinished ){
// 写入数据
mIdVerifier.writeData( scence, params, data, offset, length );
}
mIdVerifier.stopWrite( scence );
检索结果通过 listener 的回调返回,应用可通过返回结果中,排在最前面,且相似度超过一定值的,认为数据属于此用户 ID。另该功能具体的调用示例可参考身份验证下载包中的demo部分。