簡體   English   中英

RSA私鑰參數不是有效的私鑰

[英]RSA private key parameter not a valid private key

我的私鑰字符串示例(在文件中-private.key):
“ aced 0005 7372 0014 6a61 7661 2e73 6563 7572 6974 792e 4b65 7952 6570 bdf9 4fb3 889a a543 0200 044c 0009 616c 676f 7269 7468 6d74 0012 4c6a 6176 612f 6c61 6e67 2f53 7472 696e 673b 6b4006 7e00 014c 0004 7479 7065 7400 1b4c 6a61 7661 2f73 6563 7572 6974 792f 4b65 7952 6570 2454 7970 653b 7870 7400 0352 5341 7572 0002 5b42 acf3 17f8 0608 54e0 0200 0078 7000 0001 5830 8201 5402 0100 300d 0609 4886 3a02 0100 0241 008d 442f 2df6 7e5d 6e48 16a9 70a1 9006 c932 1c47 71de 6cb7 81eb 8483 e5e4 73ee b06f 5e73 ed1e 851d 54f1 2d86 6491 479a d314 8897 f7e6 85dc 65ca f1f9b 0109a 0103 C09C AC43 2d59 416E 258E a6a3 c4bb cc6d BCF1 7b5b 24d6 ff95 A146 2040 4d27 a92d cb9e CCAA 3519 fc85 50D1 022100分貝b9b2 a4c4 3ef6 4780 303C 6798 819f 1a9a 04ca DCED 0f9e 0cfd b4a5 75f​​5 bdf0 F502 2100 A496 8e0e D531 5e0b b427 6966 2b55 546B 2a8a a5d0 dcf4 bbfd 7ce9 1c56 d79c 13cb 0220 2736 8cdb 3aea c1a9 2107 7ac0 4247 5fcd af8f 0b65 4229 775b 7a2b b31b ca2f 8bc1 0220 28e3 e6a3 34c0 3117 4348 cf5c 7f3b 77f3b 7f3b 03b 0e3b 0e7b3e 0e3b3e6b3b6b0bf3b6b0bf3b0b0b0b0b0b0b0b7b3b0bf7b0fb7b0fb7b0fb7b0bd7b3b0bfb7b0dbfbfbfbfbf7bfbfbbfdfbfbfbfdf7bf7bff7bf7bfbfbff7b7bfbfbfbfdfc7b7bfbfbfdfbfbfdfc 90e1 f20a c9df 8d30 f778 c729 e074 0006 504b 4353 2338 7e72 0019 6a61 7661 2e73 6563 7572 6974 792e 4b65 7952 6570 2454 7970 6500 0000 0000 0000 0012 0000 7872 000e 6a61 7661 2000060000 0000e 00e 672e 456e 1200 4154 45“

php中的示例代碼:

echo $crypttext="PzTy-l1AWHHJ3CrynbmAfv-YWi1hpPSfv-gZbU3HeguShy_NbjytMVDKbSfkfw7afWrhH4_Weq5Lwu_jsJKM4w";
$fp=fopen("private.key","r");
$priv_key=fread($fp,8192);
fclose($fp);

openssl_private_decrypt(base64_decode($crypttext ), $newsource, $priv_key ) ;
echo "String decrypt : $newsource";

我收到“ openssl_private_decrypt():密鑰參數不是有效的私鑰”錯誤。

生成和加密源

package ia;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;


public class EncryptionUntil {
/**
 * String to hold name of the encryption algorithm.
 */
public static final String ALGORITHM = "RSA";

/**
 * String to hold the name of the private key file.
 */
public static final String PRIVATE_KEY_FILE = "C:/keys/private/private.key";

/**
 * String to hold name of the public key file.
 */
public static final String PUBLIC_KEY_FILE = "C:/keys/public/public.key";

/**
 * Generate key which contains a pair of private and public key using 1024
 * bytes. Store the set of keys in Prvate.key and Public.key files.
 * 
 * @throws NoSuchAlgorithmException
 * @throws IOException
 * @throws FileNotFoundException
 */
public static void generateKey() {
    try {
        final KeyPairGenerator keyGen = KeyPairGenerator
                .getInstance(ALGORITHM);
        keyGen.initialize(512);
        final KeyPair key = keyGen.generateKeyPair();

        File privateKeyFile = new File(PRIVATE_KEY_FILE);
        File publicKeyFile = new File(PUBLIC_KEY_FILE);

        // Create files to store public and private key
        if (privateKeyFile.getParentFile() != null) {
            privateKeyFile.getParentFile().mkdirs();
        }
        privateKeyFile.createNewFile();

        if (publicKeyFile.getParentFile() != null) {
            publicKeyFile.getParentFile().mkdirs();
        }
        publicKeyFile.createNewFile();

        // Saving the Public key in a file
        ObjectOutputStream publicKeyOS = new ObjectOutputStream(
                new FileOutputStream(publicKeyFile));
        publicKeyOS.writeObject(key.getPublic());
        publicKeyOS.close();

        // Saving the Private key in a file
        ObjectOutputStream privateKeyOS = new ObjectOutputStream(
                new FileOutputStream(privateKeyFile));
        privateKeyOS.writeObject(key.getPrivate());
        privateKeyOS.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

/**
 * The method checks if the pair of public and private key has been
 * generated.
 * 
 * @return flag indicating if the pair of keys were generated.
 */
public static boolean areKeysPresent() {

    File privateKey = new File(PRIVATE_KEY_FILE);
    File publicKey = new File(PUBLIC_KEY_FILE);

    if (privateKey.exists() && publicKey.exists()) {
        return true;
    }
    return false;
}

/**
 * Encrypt the plain text using public key.
 * 
 * @param text
 *            : original plain text
 * @param key
 *            :The public key
 * @return Encrypted text
 * @throws java.lang.Exception
 */
public static byte[] encrypt(String text, PublicKey key) {
    byte[] cipherText = null;
    try {
        // get an RSA cipher object and print the provider
        final Cipher cipher = Cipher.getInstance(ALGORITHM);
        // encrypt the plain text using the public key
        cipher.init(Cipher.ENCRYPT_MODE, key);
        cipherText = cipher.doFinal(text.getBytes());

    } catch (Exception e) {
        e.printStackTrace();
    }
    return cipherText;
}

/**
 * Decrypt text using private key.
 * 
 * @param text
 *            :encrypted text
 * @param key
 *            :The private key
 * @return plain text
 * @throws java.lang.Exception
 */
public static String decrypt(byte[] text, PrivateKey key) {
    byte[] dectyptedText = null;
    try {
        // get an RSA cipher object and print the provider
        final Cipher cipher = Cipher.getInstance(ALGORITHM);

        // decrypt the text using the private key
        cipher.init(Cipher.DECRYPT_MODE, key);
        dectyptedText = cipher.doFinal(text);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return new String(dectyptedText);
}

    public static void encDecrypt (String originalText) throws FileNotFoundException, IOException, ClassNotFoundException{
        ObjectInputStream inputStream = null;

        // Encrypt the string using the public key
        inputStream = new ObjectInputStream(new FileInputStream(
                PUBLIC_KEY_FILE));
        final PublicKey publicKey = (PublicKey) inputStream.readObject();
        final byte[] cipherText = encrypt(originalText, publicKey);
        final String cipherText64 = Base64.encodeBase64URLSafeString(cipherText);


        // Decrypt the cipher text using the private key.
        inputStream = new ObjectInputStream(new FileInputStream(
                PRIVATE_KEY_FILE));
        final PrivateKey privateKey = (PrivateKey) inputStream.readObject();
        final String plainText = decrypt(Base64.decodeBase64(cipherText64), privateKey);

        // Printing the Original, Encrypted and Decrypted Text
        System.out.println("Original Text: " + originalText);
        //System.out.println("Encrypted Text: " + new String(cipherText));
        System.out.println("Base 64 Text: " +cipherText64);
        System.out.println("Decrypted Text: " + plainText);


    }
/**
 * Test the EncryptionUntil
 */
public static void main(String[] args) {

    try {

        // Check if the pair of keys are present else generate those.
        if (!areKeysPresent()) {
            // Method generates a pair of keys using the RSA algorithm and
            // stores it
            // in their respective files
            generateKey();
        }

        final String originalText = "004477";
        Date dd = new Date();
        System.out.println(dd);
        final String currentTime = String.valueOf(dd.getTime());

        encDecrypt(originalText);
        encDecrypt(currentTime);

    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

您嘗試解碼的數據不是RSA密鑰的預期格式。 對其進行十六進制轉儲顯示:

0000000: aced 0005 7372 0014 6a61 7661 2e73 6563  ....sr..java.sec
0000010: 7572 6974 792e 4b65 7952 6570 bdf9 4fb3  urity.KeyRep..O.
0000020: 889a a543 0200 044c 0009 616c 676f 7269  ...C...L..algori
0000030: 7468 6d74 0012 4c6a 6176 612f 6c61 6e67  thmt..Ljava/lang
0000040: 2f53 7472 696e 673b 5b00 0765 6e63 6f64  /String;[..encod
0000050: 6564 7400 025b 424c 0006 666f 726d 6174  edt..[BL..format
0000060: 7100 7e00 014c 0004 7479 7065 7400 1b4c  q.~..L..typet..L
0000070: 6a61 7661 2f73 6563 7572 6974 792f 4b65  java/security/Ke
0000080: 7952 6570 2454 7970 653b 7870 7400 0352  yRep$Type;xpt..R
0000090: 5341 7572 0002 5b42 acf3 17f8 0608 54e0  SAur..[B......T.
00000a0: 0200 0078 7000 0001 5830 8201 5402 0100  ...xp...X0..T...
00000b0: 300d 0609 2a86 4886 f70d 0101 0105 0004  0...*.H.........
00000c0: 8201 3e30 8201 3a02 0100 0241 008d 442f  ..>0..:....A..D/
00000d0: 2df6 7e5d 6e48 16a9 70a1 9006 c932 1c47  -.~]nH..p....2.G
00000e0: 71de 6cb7 81eb 8483 e5e4 73ee b06f 5e73  q.l.......s..o^s
00000f0: ed1e 851d 54f1 2d86 6491 479a d314 8897  ....T.-.d.G.....
0000100: f7e6 85dc 65ca f1f9 318e cc41 4702 0301  ....e...1..AG...
0000110: 0001 0240 2306 f713 d47c bcb9 ed92 00ed  ...@#....|......
0000120: 7681 f9cc c56a 11a5 005b c09c ac43 2d59  v....j...[...C-Y
0000130: 416e 258e a6a3 c4bb cc6d bcf1 7b5b 24d6  An%......m..{[$.

這看起來像某種Java序列化格式。 您需要將其轉換為OpenSSL支持的格式(例如DER),然后使用openssl_pkey_get_private()加載它。

您正在序列化Java對象,然后在PHP中將它們讀取為字節數組,然后嘗試直接將它們用作鍵。 這只是行不通的。

首先,您需要以可互換的格式輸出密鑰對。 接下來,您不能只將這些字節讀入內存並將它們視為密鑰對。 您需要用PHP解碼格式以重新構成密鑰對。 您可以使用openssl來做到這一點。

在Java中,您可以DER格式寫出密鑰對。 像這樣修改您的代碼,例如:

// Saving the Public key in a file
FileOutputStream publicKeyOS = new FileOutputStream(publicKeyFile);
publicKeyOS.write(key.getPublic().getEncoded());
publicKeyOS.close();

// Saving the Private key in a file
FileOutputStream privateKeyOS = new FileOutputStream(privateKeyFile);
privateKeyOS.write(key.getPrivate().getEncoded());
privateKeyOS.close();

您可以在shell提示符下使用openssl驗證這些文件,如下所示:

$ openssl rsa -inform DER -in private.key
$ openssl rsa -inform DER -pubin -in public.key

在PHP中,您可以讀取這些二進制文件並用openssl解碼DER ...好吧,看來您不能在openssl的PHP實現中直接使用DER,因此必須首先將DER轉換為PEM

最后,您可以使用openssl 將PEM解碼為公用密鑰和專用密鑰。

例如,在PHP中:

// (You could also convert the DER to PEM elsewhere, before PHP reads the files.)
function der2pem($der_data, $kind)
{
  $pem = chunk_split(base64_encode($der_data), 64, "\n");
  $pem = "-----BEGIN ".$kind."-----\n".$pem."-----END ".$kind."-----\n";
  return $pem;
}

function to_pem($filename, $kind)
{
  // TODO: handle errors
  $f = fopen($filename, "r");
  $der = fread($f, filesize($filename));
  $pem = der2pem($der, $kind);
  fclose($f);
  return $pem;
}

function load_private_key($filename)
{
  $pem = to_pem($filename, "PRIVATE KEY");
  return openssl_pkey_get_private($pem);
}

function load_public_key($filename)
{
  $pem = to_pem($filename, "PUBLIC KEY");
  return openssl_pkey_get_public($pem);
}

$private_key = load_private_key("private.key");

$public_key = load_public_key("public.key");

if (openssl_public_encrypt("Hello", $ciphertext, $public_key))
{
  if (openssl_private_decrypt($ciphertext, $recovered_plaintext, $private_key))
  {
    echo $recovered_plaintext;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM