RSA ERROR

这周用了三天的时间学WebService,第一天在网上找资料认识WebService,第二天早上的时候自己发布了WebService,学习了注解,并成功的访问到了发布的WSDL。余下的一天半左右用在了学习SRA,第一次接触SRA是在大三上学期信息安全的课上,当时也实现了SRA算法并且印象中没有遇到什么bug,这次遇到了一些,记录一下。

1. IOException: Detect premature EOF

1.1 问题背景
在文档中直接复制一对秘钥(公钥和私钥),在用其加密和解密的时候出现了java.security.InvalidKeyException: IOException: Detect premature EOF错误。
公钥和私钥

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: Detect premature EOF
	at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
	at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
	at SINO.encrypt.ras.RsaSignatureByte.getEncryptCipherByPublicKey(RsaSignatureByte.java:164)
	at SINO.encrypt.ras.RsaSignatureString.encryptByPublicKey(RsaSignatureString.java:149)
	at SINO.TestXyjkpt.main(TestXyjkpt.java:24)
Caused by: java.security.InvalidKeyException: IOException: Detect premature EOF
	at sun.security.x509.X509Key.decode(X509Key.java:380)
	at sun.security.x509.X509Key.decode(X509Key.java:386)
	at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
	at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
	at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
	... 4 more

1.2 问题分析:
Detect premature EOF(End Of File)检测到更早的文件结尾,私钥不正确。
自己写了一个生成秘钥对的代码,发现私钥的长度不正确,文档中的私钥是错误的,应该是私钥长度过长,在编辑文档的时只截取了部分私钥。
密钥对
1.3 解决方法:
更改秘钥。

2. IOException: algid parse error, not a sequence

2.1 问题背景
现有两对秘钥,用于Service和ServiceTest之间进行通信,我在两个文件中分别写了

	static String publicKeyA;
	static String privateKeyA;
 
	static {
        try {
            Map<String, Object> keyMap = RsaUtil.genKeyPair();
            publicKeyA = RsaUtil.getPublicKey(keyMap);
            privateKeyA = RsaUtil.getPrivateKey(keyMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
	at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
	at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
	at SINO.encrypt.ras.RsaUtil.encryptByPublicKey(RsaUtil.java:229)
	at SINO.ServiceTest.main(ServiceTest.java:61)
Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
	at sun.security.x509.X509Key.decode(X509Key.java:380)
	at sun.security.x509.X509Key.decode(X509Key.java:386)
	at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
	at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
	at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
	... 3 more

来生成秘钥,Service在用其私钥进行解密的时候出现该错误信息。
2.2 错误分析(??)
错误含义:非序列,类型转换错误,一般出现这个情况的原因是秘钥不是pks8 格式。
2.3 解决方法
直接给定秘钥,不生成。
解决方法

在Stack Overflow上找到的另一种答案,在获取私钥之前调用

java.security.Security.addProvider(
         new org.bouncycastle.jce.provider.BouncyCastleProvider()
);

3.Data must start with zero

3.1 问题背景
加密解密返回的都是byte[],直接解密是没有问题,在ServiceTest中用toString()将其变成字符串进行参数传递,在Service中用getBytes()得到byte[]进行加密解密操作,出现Data must start with zero.
错误示例:

            String string = RsaUtil.encryptByPublicKey(info, Service.publicKeyA).toString();
            System.out.println("加密后:" + string);
            byte[] date = string.getBytes();
	    byte[] date_decryption = RsaUtil.decryptByPrivateKey(date,Service.privateKeyA);
	    System.out.println("解密后:" + new String(date_decryption)); 

错误

javax.crypto.BadPaddingException: Data must start with zero
	at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
	at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
	at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
	at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
	at javax.crypto.Cipher.doFinal(DashoA13*..)
	at SINO.encrypt.ras.RsaUtil.decryptByPrivateKey(RsaUtil.java:164)
	at SINO.Service.getPhoneInfo(Service.java:83)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.sun.xml.internal.ws.api.server.InstanceResolver$1.invoke(InstanceResolver.java:235)
	at com.sun.xml.internal.ws.server.InvokerTube$2.invoke(InvokerTube.java:135)
	at com.sun.xml.internal.ws.server.sei.EndpointMethodHandler.invoke(EndpointMethodHandler.java:246)
	at com.sun.xml.internal.ws.server.sei.SEIInvokerTube.processRequest(SEIInvokerTube.java:82)
	at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:587)
	at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:546)
	at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:531)
	at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:428)
	at com.sun.xml.internal.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:232)
	at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:460)
	at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:233)
	at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:95)
	at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80)
	at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
	at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
	at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
	at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:557)
	at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
	at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:529)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
	at java.lang.Thread.run(Thread.java:662)

3.2 问题分析
由于byte值可能是一位到三位,无法知道某一个byte是在哪里结束。因此解析时出错。
3.3 解决方法
要在加密后产生的byte数组转成string时要在各byte之间加个标识符,然后再根据空格分隔转换回byte数组。
代码:

//字节数组转字符串
public static String bytesToString(byte[]  info) {
	     String result = "";
	     for (Byte bytes : info) {
	         result += bytes.toString() + " ";
	     }
	     return result;
	}
//字符串转字节数组
public static byte[] stringToByte(String info) {
	String[] strArr = info.split(" ");
	 int len = strArr.length;		    
	 // 转回bytes
	 byte[]  temp= new byte[len];
	 for (int i = 0; i < len; i++) {
	      temp[i] = Byte.parseByte(strArr[i]);
	 }
	 return temp;
}

结果

当你看到这个错误消息 `Error connecting to agent: No such file or directory`,意味着你在尝试连接到 SSH 密钥代理 (SSH Agent) 时找不到对应的文件。SSH 密钥代理是一个后台进程,用于存储私钥并自动处理身份验证请求。 以下是可能导致此问题的一些原因及相应的解决办法: 1. **密钥文件不存在**: 检查提供的路径 `/home/zhangjian/.ssh/id_rsa` 是否指向正确的私钥文件。如果你刚刚创建过密钥,可能还没来得及将密钥添加到代理中。请确认 id_rsa 文件确实存在于指定目录,并且文件本身是可用的。 2. **密钥代理未启动**: 确认 SSH 负责管理密钥的程序 `ssh-agent` 是否正在运行。如果是 Windows 系统,通常是在命令提示符下使用 `eval $(ssh-agent)` 启动的。如果没有启动,请运行: ``` eval $(ssh-agent) ``` 接着,输入 `ssh-add ~/.ssh/id_rsa` 加载你的密钥。 3. **环境变量设置不正确**: 确保你的系统设置了 `SSH_AUTH_SOCK` 环境变量,这应该指向正在运行的 SSH 密钥代理的 socket。你可以在终端查看当前值,如果没有设置,可能需要手动配置。 4. **跨用户权限问题**: 如果你是从一个用户切换到了另一个用户,SSH 密钥可能不会跟随。在这种情况下,你需要手动将私钥移动到新用户的 `.ssh` 目录,然后重新加载。 5. **代理服务不可用**: 如果使用的是第三方代理服务(比如 Keybase 或 GitLab 的个人访问令牌),确保它们正常工作并且可以访问。 尝试上述建议,如果问题仍未解决,可能需要详细检查系统的日志文件或寻求更专业的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值