打包打了无数次,第一次被签名问题卡住的时候,我盯着Unity编辑器里那句Unable to sign the application; please provide passwords!看了整整五分钟。这个报错看起来像是密码不对,实际上呢,大部分情况跟密码半毛钱关系都没有。我自己第一次遇到是在帮朋友出一个安卓包,那天差点把Unity的Player Settings翻了个底朝天,最后发现根源竟然是创建签名文件时的一个默认选项没勾。
这类报错在Unity 2019之后的版本里相当常见,尤其是刚接触安卓打包的开发者,或者是从旧项目迁移升级、换了一台新电脑重新配环境的老手,都容易踩进去。它本身不算复杂的编译错误,但报错信息给得不够直白,导致很多人绕着弯排查。
如果你现在正被这个报错卡住,或者单纯想搞清楚Unity的签名机制到底是怎么回事,这篇内容会帮你把整个流程理顺,还能顺手避开几个我踩过的坑。
1. 报错出现的位置和它真正的含义
先说结论:Unable to sign the application; please provide passwords!这句话翻译成人话就是“Unity在给安卓APK做签名的时候,找不到可用的签名证书和对应密码”。
安卓应用要求所有APK必须经过数字签名才能安装到设备上,这是Android系统的安全机制。Unity打包时会把这一步自动完成,但前提是它需要拿到两部分东西:
- 一个有效的keystore文件(存放密钥库)
- 这个keystore的storepass和keypass密码
如果你在Project Settings里没有正确配置这两样东西,或者配置了但密码对不上,构建时就会报出上面这行英文。实际操作中,绝大多数人看到这个报错后的第一反应是去检查密码有没有输错。我不否认有这个可能,但根据我帮别人排查的经验,密码输错只占很小一部分比例。
更多时候,问题出在下面这几个环节:
- 第一次打包安卓,根本没创建过keystore,签名区域一片空白
- 项目是从别人那里拷来的,签名路径指向了另一台电脑上的文件
- 使用了Custom Main Manifest或Custom Gradle Template,导致Unity的自动签名流程被绕过
- Unity版本升级后,Player Settings里的签名配置被重置了
所以处理这个报错的第一步,不是去猜密码,而是先确认签名配置区域的完整状态。你只需要打开Edit菜单下的Project Settings,切到Player选项卡,再找到Android平台下的Publishing Settings,就能看到签名相关的所有选项。
1.1 签名面板里各选项的作用
这里我建议你先花两分钟把Publishing Settings里的内容看明白,以后再遇到签名报错就能快速定位。
面板主要包含以下几块:
- Keystore Manager区域:用于创建和管理keystore文件
- Build的签名配置:Path、Password等字段,分别对应keystore文件路径、密钥库密码、密钥别名和密钥密码
- Custom Main Manifest、Custom Gradle Template等复选框:勾选后启用自定义模板
- Build App Bundle (Google Play):用于生成AAB格式包
签名配置里最核心的是四个信息点:
| 配置项 | 作用 | 填错后的表现 |
|---|---|---|
| Keystore路径 | 指定keystore文件所在位置 | Unity找不到文件,直接报错 |
| Keystore密码 | 解开keystore文件的密码 | 抛出Invalid keystore format或签名失败 |
| Key别名 | 指定使用keystore中的哪一把密钥 | 报错提示找不到别名 |
| Key密码 | 这把密钥自己的密码 | 报错提示keystore被篡改或密码错误 |
看明白这张表,你就能理解为什么直接往密码框里反复输入往往没有效果——因为真正缺的可能不是密码,而是整个keystore文件,或者路径根本没有指向一个有效文件。
2. 新项目第一次打包时的完整解决流程
如果你的项目是全新的,或者之前从来没有在Unity里做过安卓签名,那解决办法很直接:创建一个keystore文件,填好各项信息,重新打包。
我先说创建keystore的两种方式,然后详细拆解我推荐的那套流程。
2.1 方式一:Unity内置的Keystore Manager
Unity从2017版本开始内置了Keystore Manager,可以免去下载Android Studio或者命令行工具。具体操作是:
- 在Publishing Settings里点击Keystore Manager按钮
- 下拉菜单里选择Create New Keystore
- 选择保存路径,输入keystore密码并确认
- 接着在Key区域点击Create New Key
- 填写别名、密码、有效期以及组织信息
这套操作完后,Unity会自动把新keystore的路径和密码填到签名配置里,你理论上不需要手输密码。但这里有个容易忽略的点:创建Key的时候,下方的Organizational Unit和Organization字段我有几次随手填了中文,后续在某些Gradle版本下会报编码相关的警告。经验之谈,这些字段尽量用英文。
2.2 方式二:命令行keytool创建(推荐熟练用户)
用Unity内置工具当然方便,但如果你计划长期维护同一套签名,或者需要把签名文件共享给团队成员,用命令行生成的keystore在可控性上更强。
keytool -genkeypair -v -keystore myapp.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000执行后系统会依次提示你输入keystore密码、姓名、组织单位、城市等信息。需要注意,keytool提示的“姓名与姓氏”在实际的证书信息里是CN字段,一般填项目名或你的名字就行。
生成完毕后,把myapp.keystore放到项目外的独立目录,比如D:\AndroidKeystore\,路径里尽量不要有中文和空格。然后在Unity签名配置里选择Use Existing Keystore,选好文件,填上创建时设置的密码。
2.3 填完密码依然报错的隐藏原因
这里我必须提一个隐藏很深的坑:Unity中有部分版本在填写签名密码后,不会自动把密码同步到Gradle配置里。如果你的项目启用了Custom Gradle Template,Unity生成Gradle工程时可能不会读取Player Settings里的密码,而是使用默认的模板配置。
具体表现就是你确认签名区域的路径和密码都填对了,一打包还是同样的报错。这时候的处理办法是:
- 在Player Settings里勾选Custom Gradle Template
- 点击下方出现的模板链接,打开gradleTemplate.properties
- 检查是否存在android.enableJetifier或类似配置,没有就加上
- 在Project文件夹里找到gradleTemplate.properties,确认是否包含了签名信息
如果你不想深究模板内容的含义,更直接的办法是取消勾选Custom Main Manifest和Custom Gradle Template,让Unity用默认方式处理。默认情况下,Unity会正确处理签名配置。
但如果你确实需要自定义Gradle模板(比如要改包名、调整依赖),那就得手动检查模板里是否缺少了签名参数。这也是我要特别强调的:模板是好东西,但启用之前要想清楚自己要不要动它。
3. 手动指定密码的另类思路:利用Unity的隐藏配置
关于签名密码,Unity其实留了一个偏门的手动指定入口,可以通过命令行加参数的方式传入。这在自动化构建或者CI/CD流水线中非常实用。
比如你可以在Build命令里追加如下参数:
Unity -batchmode -quit -projectPath /path/to/project -executeMethod BuildScript.PerformBuild -keystorePass "mypassword" -keyaliasPass "mykeypass"然后在自己的编辑器脚本里用Environment.GetCommandLineArgs()读取这些值,再赋给PlayerSettings.keystorePass和PlayerSettings.keyaliasPass。这样既能避免密码硬编码在项目里,也能解决一些特殊场景下Unity不读取签名密码的怪毛病。
如果你只是为了本地打包解决报错,不需要走这么复杂,但我好几个用Jenkins出包的朋友都靠这个方案解决了自动化构建时的签名问题。
4. 常见问题与排查技巧实录
前面把基本原理和操作流程都拆过一遍了,下面整理我自己和身边人真实遇到过的一些报错场景。
4.1 密码明明正确,却提示签名失败
有一次帮同事排查,他的报错信息不是Unable to sign the application,而是不同版本的keystore证书格式识别问题。后来发现他用的keystore文件是从一台Mac电脑上拷贝过来的,来源文件本身没问题,问题出在他的Unity版本太旧。
旧版Unity内置的Java环境版本较低,打不开新版keytool生成的PKCS12格式keystore。这类情况下你有两种选择:
- 换用高版本Unity重新打包
- 用新版keytool把keystore转换成旧格式
转换命令参考:
keytool -importkeystore -srckeystore old.keystore -destkeystore new.keystore -deststoretype JKS转换成功后,用new.keystore替换原来的文件,再重新填路径和密码。
4.2 多人协作时代码没问题但只有某台电脑报错
这个场景我在团队里碰到过好几次。项目在同事A的电脑上打包一切都正常,代码同步到同事B的电脑上,一打包就报Unable to sign。究其原因,Unity的库函数里对中文路径处理不友好,加上每个人放置keystore的位置不同,非常容易发生这种情况。
我的建议是,团队协作时应统一签名文件路径,或者干脆把keystore放进项目根目录下(记住千万别提交到公开仓库),这样换电脑就不会因为路径问题报错了。
另外需要注意,Unity的签名密码是会保存在Library/PersistedCache里的,如果你的项目也提交到了版本控制,而队友拉取代码后Library没有同步,那签名信息在他们本地就是空的,需要重新填写一次。经验之谈:第一次配好后,可以提醒队友在打包前先打开Publishing Settings看一眼密码框是否已经被填充。
4.3 从Asset Store导入的资源引发签名报错
这是比较冷门的一种情况。某些第三方插件在导入时会修改Gradle配置,或者自带一套自定义签名配置,和你的项目配置起了冲突。
排查方法是:先禁用或移出所有第三方插件,复用你之前的构建流程看看是否报错。如果不报错了,逐个重新导入插件并尝试构建,定位到具体是哪个插件导致的。在我实际遇到过的情况里,广告类SDK和某些推送插件做这种事的概率最高。
4.4 构建App Bundle时报错而APK正常
你可能会遇到一个问题:Build APK完全正常,换成Build App Bundle就报Unable to sign。这是因为AAB要求签名配置必须完整,且签名密码不能为空。Unity 2019之后的版本对于AAB格式做了更严格的检查。
解决方法和普通签名一致,但要额外确认一处:在Publishing Settings里勾选了Build App Bundle后,下方会增加一行签名相关的提示,仔细读它能帮你少走很多弯路。
4.5 重置签名配置的最快路径
万一排查过程中你把自己绕晕了,最省事的办法不是反复在配置框里改来改去,而是直接在Project Settings里重置签名配置。
你可以找到Publishing Settings下方的Reset按钮(不同Unity版本位置略有差异),点击后Unity会清空签名区域的所有字段。然后重新按照创建keystore的流程走一遍,比手动一个一个字段清空要快得多,也有助于排除之前留下的错误信息。
5. 从报错到构建成功的一点心得体会
最后说点实际经验。这个报错本身不难,真正浪费时间的是它容易让人误判方向。我见过有人为了处理这个小问题,把自己的Java环境重装了一遍,还有人把Gradle缓存整个删除重新下载,结果都无功而返。早点把Publishing Settings里的每个字段弄明白,遇到报错时按路径、文件、密码的顺序逐步排查,通常几分钟就能解决。
另外,签名这件事值得你建立一个固定的工作习惯:给每个项目创建一个独立的keystore,保存时把密码记录在密码管理器里,路径统一放在没有中文的目录下。这些不起眼的习惯,在项目上线半年后突然要打紧急更新包时会帮你省下大量时间。
Unity的签名流程在不同版本间有过细微变化,但核心逻辑没变——它只是需要一个有效且可读的keystore。按这个思路去排查,这个报错基本不会再拦住你。