返回顶部
首页 > 资讯 > 移动开发 >java.security.InvalidKeyException: IOException : DER input, Integer tag error关于RSA解密碰见的天坑
  • 829
分享到

java.security.InvalidKeyException: IOException : DER input, Integer tag error关于RSA解密碰见的天坑

后端android 2023-09-16 12:09:57 829人浏览 八月长安
摘要

项目场景:         安卓开发中手机号一键登入,需要得到本机号码,号码有三大运营商,所以用的时极光平台,帮我们封装好了。客户端通过认证Android SDK 后获取loginToken给服务端,服务端拿到loginToken调用一键

项目场景:

        安卓开发中手机号一键登入,需要得到本机号码,号码有三大运营商,所以用的时极光平台,帮我们封装好了。客户端通过认证Android SDK 后获取loginToken给服务端,服务端拿到loginToken调用一键认证api获取加密的手机号(基于RSA公钥),需要用对应的RSA私钥解密,但出现了java.security.InvalidKeyException: IOException : DER input, Integer tag error这个问题,意思是私钥格式不对,处理了半天,避免大家踩坑,总结出这篇文章。


问题描述

对获取到加密的手机号进行解密报的异常,先看官网的解密方案:

官方文档

官方是使用了RSA的私钥对加密的手机号进行解密,

什么是RSA?

  • 计算机中常用的加密技术分为两类:对称加密、非对称加密。

  • RSA属于非对称加密。加密、解密过程使用不同的秘钥,分为公钥、私钥。公钥可以公开,私钥不可以。

  • 对称加密:加密和解密使用相同的的秘钥Key,这个Key需要在网络上传输,不安全,因此需要非对称加密 

    我们服务端通过loginToken获取的手机号就是通过公钥来加密的,需要使用对应的私钥来进行解密,这里提供RSA相关的加解密工具网址 RSA加解密工具

        于是我应开发的需求,生成了一对带密码的RSA公私钥对(可以设置无密码,就是随机生成,但我设置了密码,就是这个行为让我报了半天的错误)

        为了验证生成的密钥对能否对症成功,我在RSA加解密工具验证的时候,发现需要带密码才能验证成功,可上面是说密码可写可不写,我当时没有在意,就任他发展,让我苦逼的在后面。


我的代码实现1

package com.lyj.biz.converter;import cn.hutool.core.util.CharsetUtil;import cn.hutool.core.util.StrUtil;import cn.hutool.crypto.asymmetric.KeyType;import cn.hutool.crypto.asymmetric.RSA;public class RSATest {    public static void main(String[] args) {        //RSA私钥        final String  JVERIFY_PRIVATE_KEY="MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIM5nBmtpZeEQCAggA" +                "MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBQ9OWtLaOumZtlrURZgNjiBIIC" +                "gIK6eSC4EUaVGJPzOMTvDEnpsCvPIMpuIgPnpQldlF5z3qhoxVJ9fbYiuSeZuYz7" +                "FM50OL2YdfcW2ajY4UcE0OlA+GVPR61fCcvr0PXYrQDjrXVQ24U52kfzxqsRlu4q" +                "LnHPdNZwI8FHA5eBp" +                "Q6f9xosqFmkhGXoENZV1cxseuT5hhcC6389V5GWG/gmtxy/ff01oHgzi1s5n6BdC" +                "9jU9ju2VfwrQn2NxygNARtMajEtWL1/pk4vmtu694zPTv7SJe2bgMPIdh5uH6ZLT" +                "dbrjsXLfwaNM39BWYJG4ZzcPl58yE8QqA6+mRkkCwvdV9n/Vs9uwXRHE3DfH1O11" +                "ZtQax5TGpEHa+XUdG6p+3ktYJmm2NUoy3ED2bVYX54" +                "fDXGh2/tV4wO+ohnpaLY6EaXf0vKWNrSzmUILahx0BcE/MY6Ea6hWemXuJFbxASD" +                "Zb4EtYbMsa5/RDAueagGuDzWFOx957/868ZcYUhs9gEozCq8WQ8WCQ6wKHoI3L3W" +                "RxQo7ROBDQ/fu0rqvT7Z5h2fMtXbiyybYkoV3TjxQP4RUCypTC2hgKK/owU4/FUG" +                "GJzLPRe2jZBeWrlqgVmKo1zLdYu6EOQ/Z7pERUbmIOnXPDWeLx7fxJCCPlSLfVWb" +                "5b37YOAZxP98kpR3tm/pXT/dDnZu3j7hmu+kldwajxwY+NNagVqwIfrUs5LOjq58" +                "Eq7KcrwvSj0ymufRm13Z2hVFepn+y5W+pDIoTNLl8mBZNI0H3TlsV89NltTvp0TT" +                "bUMXPCljfsaXNa2O7DGnVsk=";        //RSA公钥        final String  JVERIFY_PUBLIC_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADC"+                "BiQKBgQCS5mh332H7gtyJuwWtGk7DEG9J3xejIY23J"+                "0KpGsAUuSV9WrBYasDf"+                "jv6GIUeDCBIo+VxKfYJ2doRI53T3kQ9s"+                "k8N8rvDpLerhYkyD0z0lIhc5pypsW1lgbSoEQOliS/BSdIp6MOFdwIDAQAB";        //加密后的电话号码(RSA加密)        String phoneToken = "fVPnF7Ux+s1NNFrJalt+nK4oOjS+CTt/5OUca5aIfBXcfeAouPJ4Bt96iIT91hjpMvAMshixCiuX5NK9he9OrtUfkRf"+                "/mW3veLn75HJ2hQLZwwVAJ9R3AJVXgN1XMU1Kr1tWtEvdo1U1nCR9WNaYp0u4FSnrQijHjAyxMbITwfg=";        //返回解密后的电话号码(通过私钥解密)            RSA rsa = new RSA(JVERIFY_PRIVATE_KEY, JVERIFY_PUBLIC_KEY);            byte[] decrypt = rsa.decrypt(phoneToken, KeyType.PrivateKey);        System.out.println(StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8));    }}

结果:

 我是通过公钥和私钥一起来对密文进行解密的,结果报错:意思是识别不到你的私钥,不自信的我开始以为是没有使用官方答案,于是我借鉴官网的方案

package com.lyj.biz.converter;import javax.crypto.Cipher;import java.security.KeyFactory;import java.security.PrivateKey;import java.security.spec.PKCS8EncodedKeySpec;import java.util.Base64;public class RSADecrypt {public static void main(String[] args) throws Exception {    //加密手机号    String encrypted = "fVPnF7Ux+s1NNFrJalt+nK4oOjS+CTt/5OUca5aIfBXcfeAouPJ4Bt96iIT91hjpMvAMshixCiuX5NK9he9OrtUfkRf/mW3veLn75HJ2hQLZwwVAJ9R3AJVXgN1XMU1Kr1tWtEvdo1U1nCR9WNaYp0u4FSnrQijHjAyxMbITwfg=";    //RSA对应私钥    String prikey =            "MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIM5nBmtpZeEQCAggA" +                    "MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBQ9OWtLaOumZtlrURZgNjiBIIC" +                    "gIK6sCvPIMpuIgPnpQldlF5z3qhoxVJ9fbYiuSeZuYz7" +                    "FM50OL2YdfcW2ajY4UcE0OlA+GVPR61fCcvr0PXYrQDjrXVQ24U52kfzxqsRlu4q" +                    "L5muocW0MVe5PIswm9tcwzbx6zIXQAiINyYgtFmNZaIichhMnHPdNZwI8FHA5eBp" +                    "Q6f9xosqFmkhGXoENZV1cxseuT5hhcC6389V5GWG/gmtxy/ff01oHgzi1s5n6BdC" +                    "9jU9JVMtu694zPTv7SJe2bgMPIdh5uH6ZLT" +                    "dbrJSXLfwaNM39BWYJG4ZzcPl58yE8QqA6+mRkkCwvdV9n/Vs9uwXRHE3DfH1O11" +                    "ZtQakSqY8PKPTMvfahwz9yWrVQx5TGpEHa+XUdG6p+3ktYJmm2NUoy3ED2bVYX54" +                    "fDXGh2/tV4wO+ohnpaLY6EaXf0vKWNrSzmUILahx0BcE/MY6Ea6hWemXuJFbxASD" +                    "Zb4EtYbMsa5/RWQ8WCQ6wKHoI3L3W" +                    "RxQo7ROBDQ/fu0rqvT7Z5h2fMtXbiyybYkoV3TjxQP4RUCypTC2hgKK/owU4/FUG" +                    "GJzLPRe2jZBeWrlqgVmKo1zLdYu6EOQ/Z7px7fxJCCPlSLfVWb" +                    "5b37YOAZ+kldwajxwY+NNagVqwIfrUs5LOjq58" +                    "Eq7KcrwvSj0ymufRm13Z2hVFepn+y5W+pDIoTNLl8mBZNI0H3TlsV89NltTvp0TT" +                    "bUMXPCljfsaXNa2O7DGnVsk=";    String result = decrypt(encrypted, prikey);    System.out.println(result);}    public static String decrypt(String cryptograph, String prikey) throws Exception {        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(prikey));        PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);        Cipher cipher=Cipher.getInstance("RSA");        cipher.init(Cipher.DECRYPT_MODE, privateKey);        byte [] b = Base64.getDecoder().decode(cryptograph);        return new String(cipher.doFinal(b));    }}

 结果还是报错

         一开始我是纠结是不是我的密钥格式不正确,接着去查又说什么jdk的security版本不兼容了,后面我就研究那个生成工具,意识到可能是设置了密码问题,设置密码后的每次使用几乎都要带上密码,否则就是失败。

于是我抱着尝试的心态,把之前私钥的密码给清除了

 运用生成好后的私钥,替换代码中先前的私钥,果然,十分顺畅,完美解决

 无论是官方的还是自己的都行的通,成功解密出对应的手机号

 如果需要清除RSA密码的可以通过私钥在在线RSA私钥密码添加、修改、清除工具-ME2在线工具 (metools.info)修改删除,公钥主要用于加密,私钥用于解密,所以公钥可以公开,私钥记得妥善保管。


总结解决方案:

        如果碰见和我同样的问题,建议拿到私钥后去RSA在线工具修改清楚掉密码,RSA公私钥对请妥善保管,

来源地址:https://blog.csdn.net/liyingjie2001/article/details/128156745

--结束END--

本文标题: java.security.InvalidKeyException: IOException : DER input, Integer tag error关于RSA解密碰见的天坑

本文链接: https://lsjlt.com/news/409918.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作