- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们使用 phpseclib 进行数据的公钥签名,android java 用于公钥验证。但屡屡失败。
用于生成 key 并通过私钥签名的 PHP 代码
include_once("phpseclib/autoload.php");
function getKeys($keysize=2048){
$rsa = new Crypt_RSA();
//$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
//$rsa->setPublicKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$d = $rsa->createKey($keysize);
return array("publickey"=>$d['publickey'], "privatekey"=>$d['privatekey']);
}
function encryptdata($message, $encryptionKey){
$rsa = new Crypt_RSA();
//$rsa->setPublicKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
//$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
$rsa->loadKey($encryptionKey); // public key
return $rsa->encrypt($message);
}
function decryptdata($message, $decryptionKey){
$rsa = new Crypt_RSA();
// $rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
// $rsa->setPublicKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$rsa->loadKey($decryptionKey); // private key
return $rsa->decrypt($message);
}
$keys = getKeys();
file_put_contents("key.pub", $keys["publickey"]);
file_put_contents("key.priv", $keys["privatekey"]);
$publickey = file_get_contents("key.pub");
$privatekey = file_get_contents("key.priv");
//print_r($keys);
$string = "Hi I m here";
$hash = hash("sha256", $string);
$encdata = encryptdata($hash, $privatekey);
echo $base_encdata = base64_encode($encdata);
Java代码
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;
import org.apache.commons.codec.binary.Base64;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.lang.String;
class PubCheck {
public static boolean verify(String message, String signature, PublicKey publicKey) throws SignatureException{
try {
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initVerify(publicKey);
sign.update(message.getBytes("UTF-8"));
return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
} catch (Exception ex) {
throw new SignatureException(ex);
}
}
public static void main(String[] args)
throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException, SignatureException
{
String plainData = "Hi I m here";
String pkey = "MIIBCgKCAQEA2tF2g/muNw9xKTVcIkjUMvMhygtIW49yo1PgbwqDQ/w9MSfEARtYYF6Tenfz0twaR/eI14GXmlIffflORe4eaSuMBhwQFOIKU/1+v1BV3RLqGGblvHTVaMVm49AGiqxNnh1LBbcSrC5UhMqlL/HGiku0oYsbjLzwcLc5ac6aBQVD60wWGNm1g26lRQGRbCLqxVfcWKT3AMvEQK3cEx/En7/5Vg1V8xnJraNMrO8UGnaX8LLJFzYJiSCEShh7F+pMHbf4MaBekw7Aaf5hPJtczNsR137R92Be3OP4idI5NLmTV+Pi1DWlxhjEhswKH88SP+gsW31gS7B/ddECUqewQwIDAQAB";
String data = "aP0nuYYA1hE5odsCkR/DcdRbBvO2Z8IOlqXf/bKZJiG8HELIop90Vno1dKC1qyHEAOXy0gtH7GtJamzoBjDZmHPT6eto9EZP/xE7xZ8L05kjp0z2thLqO7on4C6DrG++TK1j+E3T7V0UeU874WIB0AEVzu1XUKFW6aeuU67a/gdn8N2n7N/WXtlyNSVZXg8f4PeUhGvFJrhINZT7BuMMZj1gZs4wMJPAICwfvVeg02RPH0N3Ybf2iVgRuZlmtQXGTyBlCxe9ybdHzuQM6nXghpLNmaOzCypb+yVs3Da7E0b3/fKQ7JqPSquWex2ERZbIMSTC6oCzc1rOF6iKVAd92Q==";
byte[] encodedPublicKey = pkey.getBytes( "utf-8" );
//System.out.println(new String(encodedPublicKey, "UTF-8") + "\n");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( encodedPublicKey );
//PKCS8EncodedKeySpec publicKeySpec = new PKCS8EncodedKeySpec(encodedPublicKey);
KeyFactory keyFactory = KeyFactory.getInstance( "RSA" );
PublicKey publicKey = keyFactory.generatePublic( publicKeySpec );
boolean retvar = verify(plainData, data, publicKey);
// 3 - verifying content with signature and content :
/*Signature sig = Signature.getInstance( "SHA256withRSA" );
sig.initVerify( publicKey );
sig.update( data.getBytes( ) );
ret = sig.verify( sign.getBytes( ) );*/
//byte[] decoded = Base64.decodeBase64(data);
}
}
我通过编译java代码
javac -cp commons-codec-1.10.jar:. PubCheck.java
java -cp commons-codec-1.10.jar:. PubCheck
然后发现如下异常
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at PubCheck.main(PubCheck.java:67)
Caused by: java.security.InvalidKeyException: invalid key format
at sun.security.x509.X509Key.decode(X509Key.java:387)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:83)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 2 more
免责声明:我对 Java 的了解为零。我尝试的所有代码都是从网上找到的。
更新:问题终于解决了,Java 代码可以在 Maarten Bodewes 的帮助下进行验证。他提供的代码有一个变化我需要从 phpseclib 传递 PKCS1 所以我改变了
Signature sig = Signature.getInstance( "SHA256withRSAandMGF1");
到
Signature sig = Signature.getInstance( "SHA256withRSA");
PHP 代码需要更改以使用符号而不是手动加密/散列。
function getKeys($keysize=2048){
$rsa = new Crypt_RSA();
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);
$d = $rsa->createKey($keysize);
return array("publickey"=>$d['publickey'], "privatekey"=>$d['privatekey']);
}
$string = "Hi I m here";
/*
$keys = getKeys();
file_put_contents("key1.pub", $keys["publickey"]);
file_put_contents("key1.priv", $keys["privatekey"]);
die;*/
$publickey = file_get_contents("key1.pub");
$privatekey = file_get_contents("key1.priv");
$hash = new Crypt_Hash('sha256');
$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey);
$rsa->setSignatureMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->setHash('sha256');
$signature = $rsa->sign($string);
echo base64_encode($signature);
最佳答案
PKCS#1 key 与 X.509 key 几乎但不完全相同。
以下代码段将创建一个符合 Java JCA 标准的公钥。然后它将尝试执行(默认)OAEP 解密。
package nl.owlstead.stackoverflow;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
import java.util.Base64.Decoder;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class PKCS1PublicKey {
public static RSAPublicKey fromPKCS1Encoding(byte[] pkcs1EncodedPublicKey) {
// --- parse public key ---
org.bouncycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey;
try {
pkcs1PublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey
.getInstance(pkcs1EncodedPublicKey);
} catch (Exception e) {
throw new IllegalArgumentException(
"Could not parse BER PKCS#1 public key structure", e);
}
// --- convert to JCE RSAPublicKey
RSAPublicKeySpec spec = new RSAPublicKeySpec(
pkcs1PublicKey.getModulus(), pkcs1PublicKey.getPublicExponent());
KeyFactory rsaKeyFact;
try {
rsaKeyFact = KeyFactory.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("RSA KeyFactory should be available", e);
}
try {
return (RSAPublicKey) rsaKeyFact.generatePublic(spec);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException(
"Invalid RSA public key, modulus and/or exponent invalid", e);
}
}
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
String pkey = "MIIBCgKCAQEA2tF2g/muNw9xKTVcIkjUMvMhygtIW49yo1PgbwqDQ/w9MSfEARtYYF6Tenfz0twaR/eI14GXmlIffflORe4eaSuMBhwQFOIKU/1+v1BV3RLqGGblvHTVaMVm49AGiqxNnh1LBbcSrC5UhMqlL/HGiku0oYsbjLzwcLc5ac6aBQVD60wWGNm1g26lRQGRbCLqxVfcWKT3AMvEQK3cEx/En7/5Vg1V8xnJraNMrO8UGnaX8LLJFzYJiSCEShh7F+pMHbf4MaBekw7Aaf5hPJtczNsR137R92Be3OP4idI5NLmTV+Pi1DWlxhjEhswKH88SP+gsW31gS7B/ddECUqewQwIDAQAB";
Decoder decoder = Base64.getDecoder();
byte[] dpkey = decoder.decode(pkey);
RSAPublicKey publicKey = fromPKCS1Encoding(dpkey);
String plainData = "Hi I m here";
String data = "aP0nuYYA1hE5odsCkR/DcdRbBvO2Z8IOlqXf/bKZJiG8HELIop90Vno1dKC1qyHEAOXy0gtH7GtJamzoBjDZmHPT6eto9EZP/xE7xZ8L05kjp0z2thLqO7on4C6DrG++TK1j+E3T7V0UeU874WIB0AEVzu1XUKFW6aeuU67a/gdn8N2n7N/WXtlyNSVZXg8f4PeUhGvFJrhINZT7BuMMZj1gZs4wMJPAICwfvVeg02RPH0N3Ybf2iVgRuZlmtQXGTyBlCxe9ybdHzuQM6nXghpLNmaOzCypb+yVs3Da7E0b3/fKQ7JqPSquWex2ERZbIMSTC6oCzc1rOF6iKVAd92Q==";
byte[] ciphertext = decoder.decode(data);
// this will fail of course if the "signature" was generated using OAEP - use PSS signatures instead (see comments below)
verifyBC(publicKey, plainData, ciphertext);
System.out.flush();
decryptBC(publicKey, plainData, ciphertext);
System.out.flush();
decryptSun(publicKey, plainData, ciphertext);
System.out.flush();
}
private static void decryptBC(RSAPublicKey publicKey, String plainData,
byte[] ciphertext) throws Exception {
Cipher oaep = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "BC");
// this *should* fail
oaep.init(Cipher.DECRYPT_MODE, publicKey);
byte[] plaintext = oaep.doFinal(ciphertext);
System.out.println(new String(plaintext, UTF_8));
}
private static void decryptSun(RSAPublicKey publicKey, String plainData,
byte[] ciphertext) throws Exception {
Cipher oaep = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding", "SunJCE");
// this fails beautifully
oaep.init(Cipher.DECRYPT_MODE, publicKey);
byte[] plaintext = oaep.doFinal(ciphertext);
System.out.println(new String(plaintext, UTF_8));
}
private static void verifyBC(RSAPublicKey publicKey, String plainData,
byte[] ciphertext) throws Exception {
// what should work (for PKCS#1 v1.5 signatures), requires Bouncy Castle provider
Signature sig = Signature.getInstance( "SHA256withRSAandMGF1");
sig.initVerify(publicKey);
sig.update(plainData.getBytes(UTF_8));
System.out.println(sig.verify(ciphertext));
}
}
OAEP 的 SunJCE 实现将失败,因为它不会接受用于签名验证的公钥:
OAEP cannot be used to sign or verify signatures
现在这一定是我在密码学 API 中遇到的最清晰、信息量最大的异常之一。您还可以使用 Bouncy CaSTLe 提供程序,这个提供程序将“解密”哈希值。然而,OAEP 不应该这样使用,您应该使用 PSS 来验证签名。
您应该使用 PHP RSA sign
方法,使用 setHash
设置 SHA-256。
关于java - 如何RSA验证在php中生成的java中的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34522859/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!