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 方法获取:

  1. // 设置会话场景
  2. mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
  3. // 子业务执行参数,若无可以传空字符传
  4. StringBuffer params = new StringBuffer();
  5. // 设置模型操作的密码类型
  6. params.append("pwdt=" + mPwdType + ",");
  7. // 执行密码下载操作
  8. mIdVerifier.execute("ivp", "download", params.toString(), mDownloadPwdListener);

通过 mDownloadPwdListener 回调中获取的密码,进行声纹注册。

  1. // 设置会话场景
  2. mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
  3. // 设置会话类型
  4. mIdVerifier.setParameter(SpeechConstant.MFV_SST, "enroll");
  5. // 设置训练次数(可以不做设置,sdk中默认设置为5次)
  6. mIdVerifier.setParameter(SpeechConstant.MFV_RGN, "5");
  7. // 用户id
  8. mIdVerifier.setParameter(SpeechConstant.AUTH_ID, authid);
  9. // 设置监听器,开始会话
  10. mIdVerifier.startWorking(mEnrollListener);

应用通过 mEnrollListener的 onResult 方法来处理注册结果。在结果result中携带了一个返回码(0表示成功,-1为失败)和错误码,用来判别注册是否成功以及出错原因,错误码的含义如下:

错误码数值说明
MSS_ERROR_IVP_GENERAL11600正常,请继续传音频
MSS_ERROR_IVP_EXTRA_RGN_SOPPORT11601rgn超过最大支持次数9
MSS_ERROR_IVP_TRUNCATED11602音频波形幅度太大,超出系统范围,发生截幅
MSS_ERROR_IVP_MUCH_NOISE11603太多噪音
MSS_ERROR_IVP_TOO_LOW11604声音太小
MSS_ERROR_IVP_ZERO_AUDIO11605没检测到音频
MSS_ERROR_IVP_UTTER_TOO_SHORT11606音频太短
MSS_ERROR_IVP_TEXT_NOT_MATCH11607音频内容与给定文本不一致

结果中包含的字段以及各字段的含义见附录。

1.2. 声纹验证

声纹验证过程与声纹注册类似,不同之处仅在于MFV_SST需要设置为“verify”,且不用设置 MFV_RGN 参数,并且,在数字密码类型时,密码通过 VerifierUtil.generateNumberPassword 生成。其他参数的设置、验证结果的处理过程完全可参考上一节。

另外,为了达到较好的效果,请在声纹注册与验证过程中尽量与麦克风保持同样的距离(建议的最佳距离是15厘米左右)。如果距离差距较大的话,可能会对验证通过率产生较大影响。

1.3. 模型操作

声纹注册成功后,在语音云端上会生成一个对应的模型来存储声纹信息,声纹模型的操作即对模型进行查询和删除。

  1. // 设置会话场景
  2. mIdVerifier.setParameter(SpeechConstant.MFV_SCENES, "ivp");
  3. // 用户id
  4. mIdVerifier.setParameter(SpeechConstant.AUTH_ID, authid);
  5. // 子业务执行参数,若无可以传空字符传
  6. StringBuffer params3 = new StringBuffer();
  7. // 设置模型操作的密码类型
  8. params3.append("pwdt=" + mPwdType + ",");
  9. // 执行模型操作,cmd 取值为"query","delete",分别表示查询和删除
  10. 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,以指定要鉴别的组。其参数设置如下:

  1. // 设置业务场景
  2. mIdVerifier.setParameter( SpeechConstant.MFV_SCENES, scene );
  3. // 设置业务类型:鉴别(identify)
  4. mIdVerifier.setParameter( SpeechConstant.MFV_SST, "identify" );
  5. // 设置监听器,开始会话
  6. mIdVerifier.startWorking( listener );
  7. // 指定组id,最相似结果数
  8. String params = "group_id="+groudID
  9. while( !isDataFinished ){
  10. // 写入数据
  11. mIdVerifier.writeData( scence, params, data, offset, length );
  12. }
  13. mIdVerifier.stopWrite( scence );

检索结果通过 listener 的回调返回,应用可通过返回结果中,排在最前面,且相似度超过一定值的,认为数据属于此用户 ID。另该功能具体的调用示例可参考身份验证下载包中的demo部分。