`
lvmlvy_1983
  • 浏览: 29494 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux下运行main函数OAuth验证遇到的签名问题的解决办法

    博客分类:
  • java
 
阅读更多

最近做应用分享微博到新浪和腾讯的后台服务支撑的时候,发现一个问题,应用打成jar包的时候,部署到linux环境下,在请求腾讯https://open.t.qq.com/cgi-bin/request_token校验的时候后台服务抛出了SSLException:

java.lang.Exception: javax.net.ssl.SSLException: Server key
        at com.tencent.weibo.utils.QHttpClient.httpGet(QHttpClient.java:65)
        at com.tencent.weibo.utils.OAuthClient.requestToken(OAuthClient.java:50)
        at com.test.QQTest.requestToken(QQTest.java:37)
        at com.test.QQTest.main(QQTest.java:26)
Caused by: javax.net.ssl.SSLException: Server key
        at com.sun.net.ssl.internal.ssl.Handshaker.throwSSLException(Handshaker.java:850)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:150)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)
        at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
        at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
        at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
        at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
        at com.tencent.weibo.utils.QHttpClient.httpGet(QHttpClient.java:53)
        ... 3 more
Caused by: java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPublicKeyImpl
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1056)
        at java.security.Signature$Delegate.engineInitVerify(Signature.java:1088)
        at java.security.Signature.initVerify(Signature.java:420)
        at com.sun.net.ssl.internal.ssl.HandshakeMessage$DH_ServerKeyExchange.<init>(HandshakeMessage.java:773)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:145)
        ... 19 more
Caused by: java.security.NoSuchAlgorithmException: NONEwithRSA Signature not available
        at java.security.Signature.getInstance(Signature.java:193)
        at com.sun.net.ssl.internal.ssl.JsseJce.getSignature(JsseJce.java:197)
        at com.sun.net.ssl.internal.ssl.RSASignature.<init>(RSASignature.java:45)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at java.lang.Class.newInstance0(Class.java:355)
        at java.lang.Class.newInstance(Class.java:308)
        at java.security.Provider$Service.newInstance(Provider.java:1221)
        at java.security.Signature$Delegate.newInstance(Signature.java:938)
        at java.security.Signature$Delegate.chooseProvider(Signature.java:1032)
        ... 23 more

但是将其打成war包部署到tomcat中时,向腾讯发起请求的话就会正常交互;(明明一个纯后台的东西,还得跑到tomcat下,很不爽...)

 

百度找到一个解决办法,将https://open.t.qq.com/cgi-bin/request_token该成http://open.t.qq.com/cgi-bin/request_token,不过这样就要修改腾讯SDK的源码了;

 

接着调试新浪的API接口,结果直接抛空指针异常:

Exception in thread "main" java.lang.NullPointerException
        at weibo4android.http.BASE64Encoder.encode(BASE64Encoder.java:46)
        at weibo4android.http.OAuth.generateSignature(OAuth.java:161)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:125)
        at weibo4android.http.HttpClient.setHeaders(HttpClient.java:715)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:607)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:591)
        at weibo4android.http.HttpClient.getOauthRequestToken(HttpClient.java:166)
        at weibo4android.Weibo.getOAuthRequestToken(Weibo.java:1567)
        at com.test.SinaTest.requestToken(SinaTest.java:57)
        at com.test.SinaTest.main(SinaTest.java:34)

 

查看其SDK源码,发现at weibo4android.http.OAuth.generateSignature(OAuth.java:161)时

执行Mac mac = Mac.getInstance(HMAC_SHA1);的时候直接抛出异常了,其竟然没做任何处理...

} catch (NoSuchAlgorithmException ignore) {
            // should never happen
        }

将异常打印出来发现:

java.security.NoSuchAlgorithmException: Algorithm HmacSHA1 not available
        at javax.crypto.Mac.getInstance(DashoA13*..)
        at weibo4android.http.OAuth.generateSignature(OAuth.java:139)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:85)
        at weibo4android.http.OAuth.generateAuthorizationHeader(OAuth.java:125)
        at weibo4android.http.HttpClient.setHeaders(HttpClient.java:715)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:607)
        at weibo4android.http.HttpClient.httpRequest(HttpClient.java:591)
        at weibo4android.http.HttpClient.getOauthRequestToken(HttpClient.java:166)
        at weibo4android.Weibo.getOAuthRequestToken(Weibo.java:1567)
        at com.test.SinaTest.requestToken(SinaTest.java:57)
        at com.test.SinaTest.main(SinaTest.java:34)

 

继续百度,找到一个参考资料http://stackoverflow.com/questions/2856248/nosuchalgorithmexception-algorithm-hmacsha1-not-available

照着做,在sinaSDK源码Mac mac = Mac.getInstance(HMAC_SHA1);前加入

java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

然后将sunjce_provider.jar 考到lib下,sunjce_provider.jar 原来位于 $JAVA_HOME/jre/lib/ext 下;

然后执行,ok,没问题了~~

 

思考~~~why??继续咬牙看上面的参考资料http://stackoverflow.com/questions/2856248/nosuchalgorithmexception-algorithm-hmacsha1-not-available里面的回答;

回答的哥们说可能是$JAVA_HOME/jre/lib、security/java.security 中不包含SunJCE的设置,所以需要在代码中添加

 

java.security.Security.addProvider(new com.sun.crypto.provider.SunJCE());

然后又找到一个资料http://chenjianjx.iteye.com/blog/738285

可是我的java.security 中明明包含了security.provider.4=com.sun.crypto.provider.SunJCE

难道是因为找不到sunjce_provider.jar,即时配置了也不管用的原因?

于是乎,全部代码还原,全部SDK代码还原,只是在lib中添加了sunjce_provider.jar,发现所有问题都解决了~~

腾讯API的SSLException也没问题了~~

 

ok,说了这么多,就是因为缺少sunjce_provider.jar的原因,不知道为什么在tomcat中跑时没问题,难道是tomcat启动的时候加载了~~

 

继续找资料,$JAVA_HOME/jre/lib/ext 中的jar包会在jvm启动的时候自动加载,可是为什么sunjce_provider.jar没有加载?难道是什么时候跳过了$JAVA_HOME/jre/lib/ext 的加载?

看了一下,启动的命令...jre/bin/java -Xms256m -Xmx512m -Dlabel=temp -Djava.ext.dirs=../lib/ com.test.SinaTest &

 

ok,现在清楚了,在启动的时候将ext.dirs设成了=../lib/,这个时候自然不会继续加载了~~

(为什么要这样写呢,因为之前某个哥们在lib下放了需要手动改的配置文件~~)

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics