Android:如何使用证书进行HttpPost
我有一个执行HttpPost的应用程序 现在,我需要向post添加一个证书,以便接收HttpPost的服务器接受该证书 请问我该怎么办? 非常感谢您的任何建议强>Android:如何使用证书进行HttpPost,android,paypal,http-post,Android,Paypal,Http Post,我有一个执行HttpPost的应用程序 现在,我需要向post添加一个证书,以便接收HttpPost的服务器接受该证书 请问我该怎么办? 非常感谢您的任何建议 HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("https://svcs.sandbox.paypal.com/AdaptivePayments/Preapproval"); try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("https://svcs.sandbox.paypal.com/AdaptivePayments/Preapproval");
try {
httppost.addHeader("X-PAYPAL-SECURITY-USERID", "maurizio.pietrantuono_api1.db.com");
httppost.addHeader("X-PAYPAL-SECURITY-PASSWORD", "1395657583");
httppost.addHeader("X-PAYPAL-SECURITY-SIGNATURE", "A0GgTivJ6ivBB8QDTl.cZfiYK5d9AZwsFixwIUdUhJc4JXTriwpfU2zw");
httppost.addHeader("X-PAYPAL-REQUEST-DATA-FORMAT", "NV");
httppost.addHeader("X-PAYPAL-RESPONSE-DATA-FORMAT", "NV");
httppost.addHeader("X-PAYPAL-APPLICATION-ID", "APP-80W284485P519543T");
StringEntity se=new StringEntity("cancelUrl=http://your_cancel_url"+
"¤cyCode=USD"+
"&endingDate=2015-03-29T08%3A00%3A00.000Z"+
"&maxAmountPerPayment=200.00"+
"&maxNumberOfPayments=30"+
"&maxTotalAmountOfAllPayments=1500.00"+
"&pinType=NOT_REQUIRED"+
"&requestEnvelope.errorLanguage=en_US"+
"&returnUrl=http://www.google.com"+
"&startingDate=2014-04-29T07%3A00%3A00.000Z"+
"&senderEmail=mauriziop-facilitator@hotmail.it");
httppost.setEntity(se);
HttpResponse response = httpclient.execute(httppost);
在Java和Android这样的平台上,您可能面临着最合乎逻辑但最复杂的事情之一。事实证明,没有一种简单直接的方法可以实现这一点,因为有很多种类的证书,也没有一种方法可以对所有证书进行HTTP调用,因为其中一些证书可能由未知的CA签名,其他证书需要中间包才能使证书有效,等等 可能有一种方法可以帮助您将证书存储到用户的密钥库中,这样您就可以发出HTTPS请求,因为他们已经信任目标SSL证书。在这种情况下,您将创建一个新的
密钥库
,导入证书,然后发出HTTPS请求:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
// Some of these exist in more than one package, be careful to include these
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
// This would reference to your KeyStore to store the certificate
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); // This will make a new store
// In the next line, specify the file path
// You can also export the destination certificate (in your case, Paypal's)
// put it as a hardcoded `String` and work with it.
InputStream is = ...;
BufferedInputStream bis = new BufferedInputStream(is);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
Certificate cert = cf.generateCertificate(bis);
trustStore.setCertificateEntry("myAlias" + bis.available(), cert);
}
之后,应该可以向SSL服务器发出HTTP请求
----编辑---
您不需要为站点生成证书,因为该站点已经有了证书。您必须导入其已存在的证书。我给你展示了一个如何做的例子,它是在Firefox和西班牙语下完成的,但我想你会用你的语言推断出关键词
转到要导出其证书的站点。在这个例子中,我正在做Paypal
,但是你可以为任何站点做。还要考虑到一个站点可能有许多证书,这意味着,例如,https://www.paypal.com
有一个和https://sandbox.paypal.com
还有另一种完全不同的方法。你需要检查一下这个
在地址栏的左侧,单击绿色文本,上面写着Paypal,Inc(美国)
(宣布该站点拥有SSL证书)
您将看到如下屏幕:
单击更多信息
按钮,您将看到如下内容:
单击查看证书
(或类似)按钮,现在您将看到此屏幕:
单击详细信息
选项卡,在列表中逐个选择站点(在本例中,首先是VeriSign Class 3公共初级认证机构-g5
,然后是VeriSign Class 3扩展验证SSL CA
,最后是www.paypal.com
),然后,单击该屏幕底部的Export…
。您将被要求导出PEM
证书
您刚才所做的是导出整个证书链,但现在必须将其全部放在一起。只需打开一个文本文件,将刚下载的三个证书按下载顺序依次添加到,并特别注意不要添加额外的空格
这是您必须在代码中导入的证书。在我包含的代码片段中,有一个地方需要放置文件的路径,就是这个。由于您可能希望为所有客户机包含该代码,您可能需要做两件事:
- 将证书作为项目的一部分导入。这将使运行您的应用程序的任何客户端都将拥有该证书,这样您就可以使用上面的代码而无需任何修改,但当Paypal更改该证书时,您需要小心(它们通常在一段时间后过期,需要替换为新的有效证书-您可以在证书的属性中看到证书的过期时间)
- 如上所述导出证书,将其放在公共场所(例如,web服务器)每次用户运行你的应用程序时,下载它并验证密钥库中的证书是否与你刚刚读取的证书相同。如果它不存在,只需第一次导入它。如果它存在且不匹配,则更新它。否则,你不需要做任何事
- 打开服务器URL “”
- 单击URL左侧的锁定图标
- 连接-->证书信息-->证书路径
- 你必须下载所有这三个元素
- 下载bouncycastle。请务必使用1.46版本,因为Android使用的是1.46版本
- 使用此命令导入密钥:(此处密码不重要,因为我们使用密钥库只是存储密钥) keytool-list-keystore“my_keystore_path/mykeystore.bks”-provider org.bouncycastle.jce.provider.BouncyCastleProvider-provider路径“provider_path/bcprov jdkxx xxx.jar”-storetype bks-storepass“my_password”
public ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
// Register for port 443 our SSLSocketFactory with our keystore
// to the ConnectionManager
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
public SSLSocketFactory newSslSocketFactory() {
try {
// Get an instance of the Bouncy Castle KeyStore format
KeyStore trusted = KeyStore.getInstance("BKS");
// Get the raw resource, which contains the keystore with
// your trusted certificates (root and any intermediate certs)
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
// Initialize the keystore with the provided trusted certificates
// Also provide the password of the keystore
trusted.load(in, "my_password".toCharArray());
} finally {
in.close();
}
// Pass the keystore to the SSLSocketFactory. The factory is responsible
// for the verification of the server certificate.
SSLSocketFactory sf = new SSLSocketFactory(trusted);
// Hostname verification from certificate
// http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
return sf;
} catch (Exception e) {
throw new AssertionError(e);
}
}
并以这种方式使用它:
HttpClient c = new DefaultHttpClient(createClientConnectionManager(), new DefaultHttpClient().getParams());
请注意,如果使用此ClientConnectionManager,则只接受其整个证书路径位于密钥库中的站点。如果要通过此ClientConnectionManager与其他站点建立安全连接,则必须导入其他站点的证书
下面是关于如何通过扩展DefaultHttpClient来实现这一点的详细教程,这样您就不必使用那个复杂的构造函数
首先,你把你的用户名和密码放在上面的代码里,这是很危险的!!(如果不是假的话就修改!) 其次,请提供
X509TrustManager manager = null;
FileInputStream fs = null;
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
try
{
fs = new FileInputStream(System.getProperty("javax.net.ssl.trustStore"));
keyStore.load(fs, null);
}
finally
{
if (fs != null) { fs.close(); }
}
trustManagerFactory.init(keyStore);
TrustManager[] managers = trustManagerFactory.getTrustManagers();
for (TrustManager tm : managers)
{
if (tm instanceof X509TrustManager)
{
manager = (X509TrustManager) tm;
break;
}
}