Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Java加密方法转换为Php_Java_Php_Encryption_Phpseclib - Fatal编程技术网

将Java加密方法转换为Php

将Java加密方法转换为Php,java,php,encryption,phpseclib,Java,Php,Encryption,Phpseclib,我试图生成一条加密的消息发送到远程服务器,当我用Java做这件事时,我成功了,但当我用PHP做这件事时,我失败了。 我希望您能帮助我指出php版本中的错误。下面是我的代码的Java和php版本 private String encryptMessage() { String msg = ""; String message = "this is the message to send"; String modulus = "xxxxxxxxxxxxxxx";

我试图生成一条加密的消息发送到远程服务器,当我用Java做这件事时,我成功了,但当我用PHP做这件事时,我失败了。 我希望您能帮助我指出php版本中的错误。下面是我的代码的Java和php版本

 private String encryptMessage()  {
    String msg = "";
    String message = "this is the message to send";
    String modulus = "xxxxxxxxxxxxxxx";
    String exponent = "111";
    Security.addProvider(new BouncyCastleProvider());
    RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus, 16), new BigInteger(exponent, 16));
     KeyFactory factory = KeyFactory.getInstance("RSA");
     PublicKey publicKey = factory.generatePublic(publicKeySpec);
     Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
     cipher.init(Cipher.ENCRYPT_MODE, publicKey);
     byte[] messageDataBytes = cipher.doFinal(message.getBytes("UTF8"));
     msg = Base64.getEncoder().encodeToString(messageDataBytes).replaceAll("\\r|\\n", "");

    return msg;
 }
失败的php版本

    private function encryptMessage()
{
    $message = "this is the message to send";
    $modulus = "xxxxxxxxxxxxxxx";
    $exponent = "111";
    $rsa = new RSA();
    $exponent = new BigInteger( $exponent, 16);
    $modulus = new BigInteger($modulus, 16);
    $rsa->loadKey(['n' => $modulus, 'e'=>$exponent]);
    $rsa->setPublicKey();

    $publicKey = $rsa->getPublicKey();
    openssl_public_encrypt($message, $encryptedData, $publicKey);
    return base64_encode($encryptedData);
}
对于Java,我使用的是Bouncy Castle库,而我使用的是phpseclib版本2库

谢谢

Java方法的结果:(2)2+SX3+2+SX3+2+SX3+3+XX3+3+XX3+3+XX3+3+3+JJ9+JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWRWXQH2FiMo0GUTB4+YB4+YS9dQ==

来自PHP的结果:
1.这个词的意思是:vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv4R8OVSXJ6QIEYFX9TJNQP9C1XA===

我的解决方案由3个文件组成,以获得一个完整的测试环境,并在Java中进行完整的加密和解密 并且只在PHP中使用加密

我正在使用的测试环境是Java端11.0.6+8-b520.43(没有任何依赖项,例如Bouncy Castle) 在PHP端,PHP版本7.4.6、openssl版本:openssl 1.1.1g,2020年4月21日和phpseclib 2.0.27

GenerateKeysSo.java:在模数/指数表示中生成RSA私钥/公钥对。我使用不安全的512位keylength只是为了让字符串长度稍微短一点-在生产中,您应该使用最小2048位keylength

import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;

public class GenerateKeysSo {
    public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
        System.out.println("https://stackoverflow.com/questions/53947613/rsa-public-key-generated-in-java-is-not-valid-in-php");
        System.out.println("Generate RSA keys");
        System.out.println("java version: " + Runtime.version());
        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
        //kpGen.initialize(2048, new SecureRandom());
        kpGen.initialize(512, new SecureRandom()); // don't use 512 bitlength as it is insecure !
        KeyPair keyPair = kpGen.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();
        byte[] privateKeyEncoded = privateKey.getEncoded();
        byte[] publicKeyEncoded = publicKey.getEncoded();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
        BigInteger modulus = rsaPublicKey.getModulus();
        BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();
        BigInteger publicKeyExponent = rsaPublicKey.getPublicExponent();
        System.out.println("privateKey   Base64: " + Base64.getEncoder().encodeToString(privateKeyEncoded));
        System.out.println("publicKey    Base64: " + Base64.getEncoder().encodeToString(publicKeyEncoded));
        System.out.println("modulus            : " + modulus);
        System.out.println("privateExponent    : " + privateExponent);
        System.out.println("publicExponent     : " + publicKeyExponent);
    }
}
结果很短,您需要使用copy/paste将模数、privateExponent和publicExponent的3个值复制到EncryptSo.java和 EncryptSo.php:

Generate RSA keys
java version: 11.0.6+8-b520.43
privateKey   Base64: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAgKpP+4e9D3r5Mbw4VBaQQG/LRw7nqDOWOU6p+teU2c+mTPE2apPzYUku9AaNf+BiPyjzmkWh/9d7E5jUDWfS9QIDAQABAkA9Ia5y0eFwE3uGt+kDetz64KLylhBXCHudqtR0TC169s4UfGr6EquaqX9YKmQ4ApC5mkO65Rha8V0WzV6PEUlBAiEA6XtDObkbbhAMaDXpLkzqu0I5O2e3cpTMGwCTaK/0GVkCIQCNExoakOZ1+0f5UuiztmGo7UqBpZEieiybL25H/iI2/QIhANPubzcWLy/YoWp2hRLh/q+7jPe/TWVUa3CXNTbxgEEBAiAyA22jsW8isJ0JlQ0OeUASJV3erJXRhUK/GYedWklC+QIgLnxzZVDSNNEGYFpUER0v2bIFWqVXlnm87y5LRbzWn/I=
publicKey    Base64: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAICqT/uHvQ96+TG8OFQWkEBvy0cO56gzljlOqfrXlNnPpkzxNmqT82FJLvQGjX/gYj8o85pFof/XexOY1A1n0vUCAwEAAQ==
modulus            : 6738747659637003090018178263545882875809887577706500222853194115214616163418986509701683514500084328991941041539147237736316411294805049495944982937719541
privateExponent    : 3201720015041533823900789397901821886674218828976379815054133670438877551559197501362784700723343540531608097210070472157677675484894343978127401531033921
publicExponent     : 65537
文件2是Java中的加密/解密例程(EncryptSo.Java)。将GenerateSo中的3个值粘贴到三个字符串变量moduleString, privateExponentString和publicExponentString。运行该程序,它将对消息进行加密和解密。运行PHP加密后(文件3) 您在那里有一个输出-您可以将此输出粘贴到第42行(变量ciphertextFromPhp)。这个字符串也将被解密

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;

public class EncryptSo {
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException, IOException {
        System.out.println("https://stackoverflow.com/questions/61966418/converting-a-java-encryption-method-to-php");
        System.out.println("encrypt and decrypt with Java with key generation via modulus and exponent");
        String modulusString = "7655411376708364139873444642436134423578239360576333940175884244078181837546293928220019721607335417517025652060442851820596480386882812189086919617782503";
        String privateExponentString = "6181379361775076881056852519774102589787650800051550108278185489542231510128103539355646657479306697213227070361180012317478947328351699562861534356668225";
        String publicExponentString = "65537";
        BigInteger modulusBI = new BigInteger(modulusString);
        BigInteger publicExponentBI = new BigInteger(publicExponentString,10); // 10 = numeric string
        BigInteger privateExponentBI = new BigInteger(privateExponentString,10); // 16 = hex string
        // generate private & public keys
        KeyFactory factory = KeyFactory.getInstance("RSA");
        RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulusBI, privateExponentBI);
        PrivateKey privateKeyBI = factory.generatePrivate(rsaPrivateKeySpec);
        RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulusBI, publicExponentBI);
        PublicKey publicKeyBI = factory.generatePublic(rsaPublicKeySpec);
        // encryption
        String message = "this is the message to send";
        System.out.println("message Original : " + message);
        String ciphertext = encryptMessageEnc(message, publicKeyBI);
        System.out.println("message encrypted: " + ciphertext);
        // decryption
        String decryptedtext = decryptMessageEnc(ciphertext, privateKeyBI);
        System.out.println("message decrypted: " + decryptedtext);

        System.out.println("decryption of a encrypted message from PHP");
        String ciphertextFromPhp = "B3a1v8oGVYqRpRwRwGP5KRaqaNiiXFRfTdWnz0LsI4Ek63BpXIrWsEXsVNaj1jSu4XIQNrvYHIpwdxwKQrBUUfXXwq6Pix0YfuOmz7mUJMyTerHMcVzcXIpEGAD/L0gGomfCbkahed/CimThPSO527ulazHVirOY173JjMTrWdqyFLS6L7sCD6UHkU49gW94ADkOJtRXOiIWTg==";
        System.out.println("message encrypted: " + ciphertextFromPhp);
        decryptedtext = decryptMessageEnc(ciphertext, privateKeyBI);
        System.out.println("message decrypted: " + decryptedtext);
    }
    private static String encryptMessageEnc(String message, PublicKey publicKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException, BadPaddingException, IllegalBlockSizeException {
        String msg = "";
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] ciphertextBytes = cipher.doFinal(message.getBytes("UTF8"));
        msg = Base64.getEncoder().encodeToString(ciphertextBytes).replaceAll("\\r|\\n", "");
        return msg;
    }

    private static String decryptMessageEnc(String msg, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        //Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] message = Base64.getDecoder().decode(msg);
        byte[] messageDataBytes = cipher.doFinal(message);
        return new String(messageDataBytes);
    }
}
EncryptSo的输出:

encrypt and decrypt with Java with key generation via modulus and exponent
java version: 11.0.6+8-b520.43
message Original : this is the message to send
message encrypted: WZs0jp6yMWR71I4g7Oxo54A28yDZRBs5usKYLz9NfoRkMPy7vpe+riLSZzr6mdC8XZFNGveH9HsG2maZWSxhsw==
message decrypted: this is the message to send
decryption of a encrypted message from PHP
message encrypted: B3a1v8oGVYqRpRwRwGP5KRaqaNiiXFRfTdWnz0LsI4Ek63BpXIrWsEXsVNaj1jSu4XIQNrvYHIpwdxwKQrBUUfXXwq6Pix0YfuOmz7mUJMyTerHMcVzcXIpEGAD/L0gGomfCbkahed/CimThPSO527ulazHVirOY173JjMTrWdqyFLS6L7sCD6UHkU49gW94ADkOJtRXOiIWTg==
message decrypted: this is the message to send
文件3(EncryptSo.php)是一个简单的php应用程序,它通过模数和指数构建公钥,并且需要外部依赖项“phpseclib”。我只是手动包含了这个库,没有任何编写器帮助。将模数和指数粘贴到变量modulusString和publicExponentString,并让其运行

<?php
// https://stackoverflow.com/questions/61966418/converting-a-java-encryption-method-to-php
include('phpseclib\Math\BigInteger.php');
include('phpseclib\Crypt\RSA.php');
include('phpseclib\Crypt\HASH.php');
echo 'php version: ' . PHP_VERSION . ' openssl version: ' . OPENSSL_VERSION_TEXT . ' phpseclib 2.0.27' . PHP_EOL;
$message = "this is the message to send";
$modulusString = "7655411376708364139873444642436134423578239360576333940175884244078181837546293928220019721607335417517025652060442851820596480386882812189086919617782503";
$publicExponentString = "65537";
$rsa = new \phpseclib\Crypt\RSA();
//$rsa = new Crypt_RSA();
$exponent = new phpseclib\Math\BigInteger($publicExponentString, 256);
$modulus = new phpseclib\Math\BigInteger($modulusString, 256);
$PUBLICKEY = "";
$rsa->loadKey(['n' => $modulus, 'e'=>$exponent]);
$rsa->setPublicKey();
$publicKey = $rsa->getPublicKey();
openssl_public_encrypt($message, $encryptedData, $publicKey);
$encryptedData = base64_encode($encryptedData);
echo PHP_EOL ."encryptedData base64: " . $encryptedData . PHP_EOL;
// encryptedData base64: K4DCBvi2lWbyQJGiQbZ9cXiZy49sg+Q0KKPvj7+TMObTCyWKtoQce8pmUJlDZ48+K1Fy3vHtTTZFDQzr7fkWKoeYffl171IsxOgFLz2bmjQYhrNiLy5ZI03qUX4i9MI0mtSMlITXhiryDOajHB61Cgs5cfgH+yVCJItV7cM/qMBAGnQVqoMxRAKaSOBEz/zxp3If5X9Jb5zuhA==
?>

您需要向我们展示一个示例值和每个函数生成的输出,并指定哪个是正确的输出是什么让您认为Java方法是成功的,PHP是失败的?它们看起来都很成功。@PresidentJamesK.Polk结果被发送到服务器,其接受Java版本,而拒绝PHP版本。服务器是否提供了拒绝该版本的任何线索?可能是错误消息,或异常堆栈跟踪?不幸的是,它不是。它只是告诉我加密的数据有错误。
php version: 7.4.6 openssl version: OpenSSL 1.1.1g  21 Apr 2020 phpseclib 2.0.27
encryptedData base64: M5ys/5JrlleQO5MJDVl6FvRcIUIcxXQhp00y/KLHfB1p0XRNaVaWRwV9t5NKoJmo4wKI1KQI1H9PBd71c6t3i7IWsWcS8QsebOk5iitacvgOTJBW71pjrzWkv4+M7Ge8KZ/jhCl6nQ+e9zNSkJf4HZE1NHmOzFan3pBN1gXDptj19AZPue/MxqdAIgDD538UElvhTzyWMpCJeA==