当前位置: 首页 > 面试题库 >

Java SSL DH密钥对生成-原始大小错误

潘鸿文
2023-03-14
问题内容

我目前正在将Reddit OAuth2登录实现到我的Web应用程序中。在本地进行测试时,握手和令牌交换工作正常,但是在服务器上运行(托管在“
OpenShift” DIY卡式盒上)时,出现以下错误:

java.security.InvalidAlgorithmParameterException: Prime size must be 
multiple of 64, and can only range from 512 to 1024 (inclusive)

这是结果

java.lang.RuntimeException: Could not generate DH keypair

我一天中大部分时间都在搜索,发现了从更改Java版本到使用BouncyCastle的各种解决方案。但是,我使用的是Scribe库,所以我认为如果不分叉和更改抄写员的基础,就无法实现BouncyCastle,这会破坏其目的。

也出现了安装JCE Unlimited
Strength的问题
,但是由于没有root访问权,因此我无法在OpenShift上进行安装(可能可以让他们的团队之一来执行此操作)。

使用的Java版本是(取自java -version):

本地测试机:

java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-1ubuntu1)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

OpenShift服务器:

java version "1.7.0_51"
OpenJDK Runtime Environment (rhel-2.4.4.1.el6_5-i386 u51-b02)
OpenJDK Server VM (build 24.45-b08, mixed mode)

我无所适从以解决这个问题。希望我是愚蠢的或误解了某件事,所以任何可能的解决方案都将是不错的选择!

-

编辑1

返回错误的请求代码(如前所述,使用Scribe,因此可能用处不大)。令牌端点正在https://ssl.reddit.com/api/v1/access_token使用POST。就像我上面说的,这可以在我的测试机上工作。

OAuthRequest request = new OAuthRequest(getAccessTokenVerb(), getAccessTokenEndpoint());

request.addHeader("Authorization", "Basic"
    +Base64.encode((config.getApiKey()+":"+config.getApiSecret()).getBytes()));

request.addBodyParameter("state", "none");
request.addBodyParameter(OAuthConstants.SCOPE, config.getScope());
request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());
request.addBodyParameter("grant_type", "authorization_code");

Response response = request.send();  // Errors here from Request.createConnection in the Scribe code
return getAccessTokenExtractor().extract(response.getBody());

问题答案:

首先,“无限力量”在这里无关紧要。这将解决完全不同的问题,即您无法使用使用AES-256的密码套件(如果对等方坚持要求它们根本不能握手)。JVM的位大小也无关紧要;对DH的这种限制(不是很合理的限制)在SunJCE中的“无处不在”字节码中。

您可以将BouncyCastle用作加密提供程序,而无需更改进行SSL连接的代码(在您的情况下为Scribe),但是据我所知,使BC成为首选提供程序会导致其他问题。如果仍然要尝试,请将bcprov-
version.jar放在JRE / lib / exit中,然后编辑JRE / lib / security /
java.security。或将其放在您的类路径中的任何位置,并让您的初始化代码调用java.security.Security.insertProviderAt(新的org.bouncycastle.jce.provider.BouncyCastleProvider(),位置);

我建议从您的本地系统正常工作的原因开始。当我尝试使用带有openssl的ssl.reddit.com时,它同时支持ECDHE-RSA(带P-256)和dh
2048位的DHE-RSA。Suncle Java
7确实支持并更喜欢ECDHE,我希望OpenJDK也可以,但也许不支持,或者有时不支持。我知道RedHat直到最近才在ECC的openssl转速中采用ECC,如果他们也在openjdk中这样做也不会感到惊讶。如果编译并运行以下命令(使用ssl.reddit.com
443),它将使用JRE的所有默认SSL设置(我希望/希望Scribe也正在使用)来告诉您系统上协商了哪个套件:

//nopackage DThompson 2012.08.13b
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class JustBConnectSSL {

    /* (optionally bind and) just make SSL connection, for testing reach and trust
     * uses default providers, truststore (normally JRE/lib/security/[jsse]cacerts), 
     * and keystore (normally none), override with -Djavax.net.ssl.{trust,key}Store* 
     */
    public static void main (String[] args) throws Exception {
        if( args.length < 2 ){ System.out.println ("Usage: tohost port [fromaddr [fromport]]"); return; }
        Socket sock = SSLSocketFactory.getDefault().createSocket();
        if( args.length > 2 )
            sock.bind (new InetSocketAddress (args[2], args.length>3? Integer.parseInt(args[3]): 0));
        sock.connect (new InetSocketAddress (args[0], Integer.parseInt(args[1])));
        System.out.println (sock.getInetAddress().getHostName() + " = " + sock.getInetAddress().getHostAddress());
        ((SSLSocket)sock).startHandshake();
        System.out.println ("connect okay " + ((SSLSocket)sock).getSession().getCipherSuite());
    }
}

如果测试得到_DHE_RSA_something,则您的JRE中的加密提供程序必须与Suncle的不同,可以通过Ubuntu进行更改,也可以通过系统上的某些自定义或补丁程序进行更改。如果测试得到_ECDHE_RSA_something,但OpenShift却没有,则他们可能已以某种方式禁用了ECC
/
ECDHE。如果他们能够做到最好(ECDHE-P-256至少与DH-2048一样安全,并且效率可能更高)。否则,直到Oracle修复此问题(显然是在8版中),我认为可以依靠的唯一方法是禁用DHE套件(并退回纯RSA,这可能无法抵御NSA);这在实际创建SSLSocket的代码中最简单,但是如果Scribe(像大多数Java
Web客户端一样)使用URL->



 类似资料:
  • 我试图通过遵循本教程在heroku上部署php应用程序https://devcenter.heroku.com/articles/getting-started-with-php#introduction 当前正在执行此步骤https://devcenter.heroku.com/articles/getting-started-with-php#deploy-应用程序 当我运行命令“git pu

  • 我正在尝试创建一个公钥以允许我推送到Git,但我的. ssh文件夹尚未创建。 以下是我运行的命令: $ssh-keygen-t rsa-Cemaill@me.com 生成公共/私有rsa密钥对 输入保存密钥的文件(/h/.ssh/id\u rsa): 这就是H:驱动器配置、数据、配置文件、配置文件中的全部内容。V2 我认为有一个问题,因为当我得到提示输入文件,其中保存密钥(/h//. ssh/id

  • 我试图为某些设备生成密钥时出错。我能够在运行4.4.2的三星Galaxy Note上重现错误。 我创建了一个小应用程序,只能通过从Android开发者页面“生成新私钥”下的https://developer.android.com/training/articles/keystore.html逐行复制代码来生成密钥 错误似乎发生在kpg.generateKeyPair(),在Android Key

  • 我目前正在用java编写一个加密消息传递服务,我使用的是bouncycastle PGP库。我编写了一个生成密钥对的测试程序,并对消息进行加密/解密。这已经工作了一段时间,但它最近在解密阶段停止了,给了我一个InvalidKeyException。 我做了一些研究,下载了JCE.jar文件,并将它们导入到我的项目中(通过Eclipse Project->Properties->add extern

  • 所以唯一的问题是如何从原始十六进制编码的密钥得到这个DER结构。 如果有任何帮助,我将不胜感激!

  • 如果我尝试使用OpenSSL命令行生成3TDES加密的PKCS 8密钥: 我得到: PKCS8 RFC没有说明必须使用哪种算法来创建密钥块。它确实给出了PKCS5算法作为例子。有没有办法使用OpenSSL创建一个由DES密钥加密的PKCS8密钥?如果不是,它是OpenSSL不支持的还是一个非常不标准的事情? 下面是通过OpenSSL命令行(密码测试)使用基于密码的加密创建的示例: 这里是我手工制作