2017-08-09 24 views
1

OAEP SHA-256パディング付きのRSA公開鍵とRSA秘密鍵が与えられました。私は単純にランダムな文字列を暗号化し、その結果を元に戻すように解読しようとしています。BadPaddingException RSA暗号化とJavaでの復号化

これは私が与えられている公開鍵である:

-----BEGIN PRIVATE KEY----- 
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDAUQiHdHuMBCnF 
P/7RQoRWrp62dGWQLDLP9l+3KUMlSPheN2R5jHDZ/WEGJGF2WYKxaQvv5XCocdnt 
uxVZTNM1PVyduokJaJzrSIj+jGWDd4hTWvVoS3vhds8u6W0jD3M4ayrF6c7NYuHc 
tE5YLLIgK1DTn+ZZCr3VGbScISDJ/WPx3+1YTNQDvm+T7MfjhetJqqzWIsunMUiw 
nQOQvkdjCVWpk+L10SaMrezixtIS5wfpOTjGIZ0w5VunvtsPxg1TkuvGURa9S3rS 
7D3uhDPY+V8UDMpBPso3j7TGD5axlBJcpavWeF8qde3sWztmqUFQ3JDypZWGSAe2 
d8e4mY65AgMBAAECggEAal8nwYxbHZnb5L892U7aVfuly7Nbzb+0pzRVwsBu5DuV 
LL+kslpMvTYZqUUMJ2LhF/HLaXhVtMWsTYLSDx+gHu1+wbtAOtUDHlxzcaAEMhA2 
dix0WqiNr6qAdCkmdWMBTu5vrSJigVW1KdcNElY+e+6ZeUQTK6L2Vt0t+cGVGkM4 
K5PdHcGLR1BiAf3k4BguHE4TGGnqN9dF5Rn9nPP6C7QihWzGn15efD2dAXn3Kbho 
dMIRgyYiO7uXPm2LrIjtldYb8tPus+V9SWT4hcgnJZrtd9atkqZrJ3dhQf9ZetGs 
UwTCzHJ169NNbVyrjCbcy4Uht8Na+t/94Im9hI8n0QKBgQDO6tYnwh1hPg3E+4DY 
xCiDAp7v3afJIvC9a1sBtif8KkzZTYH31ww+PRcfDPQUlk/MIDie0u6xIawnBYkC 
oN1u9erojcvQbBP0GFylP5hNxYZbI7gPA/7AiGRxyezZPOiVMwdd5fCM7Wv4kucr 
c1JCcvtPoDQcFFZOfI+wqqdWnQKBgQDt745Pvckt7/XL7wbfv4BV+cwpLNjc4/3k 
ajOLtasgpT8mc0gUH2ejHhpkuhjSUpSTrlFB8EN1kAwmBYy0GOoO9967hm6twmqk 
Q5L3OHJ96pYkf1rbyXNE1N7inh5Z3M1H5ONIaliAYLHXOzKsZvI5eUdKAJdSqFLo 
uvVCwr4PzQKBgG6W3rzDJ9a4Rr24OgYg2RIkTXQgALQko4xpm2tPwxEoPoiJv2QK 
ILYHCpuC3dU+/Qk5U2m3jPFI8OyuLask9RSABPwkBQGxMfztJF8BnVI7tvJxJceI 
uBiJDT4v0RHOVvSfIFnUMnvvzRw+z6TObvGq6JyHIDK9v98U/etLWkKVAoGAIIxF 
lmjqzUrm/8ep1A+5OYmbQQKug8D4aTeR54mpaCTSt6rLcF0/axPiHmdKn/LF+lG9 
MdzxDXLwBn952OUTl4qWwGZKW6Cdv+yyfPkOyGS/tyxovGoZR5ArESr6Eebfefc4 
lB5gDuerTDr/2o+WkQAjHV9pU9hMxyNUC5biMv0CgYEAiDlw8lBf3cQs6FxNXs9t 
whWpfL0yY7WAONvhfFB0Dpsz52gGDCYRvJekGRz6jOlKDuXJ+Mm1AX4BaufMETI5 
QseZxtVPIn+BXm0A1x8w/DifmE1JqQZmPCQPOh3eLx5nSn9LKGIbMgd17mfH3HhU 
8WX2mzWjmRA3C/CzdGfCKSk= 
-----END PRIVATE KEY----- 

私はPEMファイル「crypt_pkcs8からこのキーを読んでいます:

-----BEGIN RSA PUBLIC KEY----- 
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8tiBtDmkeS/ruY3rrkq 
dz6Lc6XWFRbI/GjPtIokrtpM+Ujyv6wX8TBqY8e03gzh+eE7VUyEVPapDnceAqgJ 
ZQah2h+N5AEQKqNDM4/1to1V0F+m1ISR7CIUU8dvU+bPk67DU5VkEtLxf+mW8/es 
hy0u6oSB04WCDPNnh+9GDF7tN7lOzBH1FxKPWIb5Gqg6GoXS+KgvQhYEk0TajIBk 
+mefzTv1D4HJlhFYybgY+/p3k4P2kM5HnbEtoVpz/PL9+94YVp5RBHTQHmk/3SAX 
RkPP34IjY6LZqTJGWQGxc64Qci54ZJsq4wSTXvfdHgUWz7eX+v1jA+GLjFExNcYZ 
nQIDAQAB 
-----END RSA PUBLIC KEY----- 

これは私が与えられている秘密鍵です。 pem "を呼び出すが、公開鍵をgRPC呼び出しからバイト配列として受け取る。ここで

は私のJavaコードです:

public class Encryption{ 
public static void main(String args){ 
    ByteString publicKey = client.getPublicKey(nonce).getRSAEncryptionKey(); 

    String strKeyPEM = ""; 
    BufferedReader br = new BufferedReader(new FileReader("crypt_pkcs8.pem")); 
    String line; 
    while ((line = br.readLine()) != null) { 
     strKeyPEM += line+"\n"; 
    } 
    br.close(); 
    byte[] pt; 
    try { 
     pt = "h".getBytes("UTF-8"); 
     byte[] ct =encrypt(publicKey, pt); 
     byte[] response= decrypt(strKeyPEM, ct); 

     assertEquals(pt, response); 
    } catch (UnsupportedEncodingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
public static byte[] encrypt(ByteString rawKey ,byte[] message){ 
    String strippedKey=stripKey(rawKey.toStringUtf8()); 

    byte[] keyBytes = Base64.getDecoder().decode(strippedKey); 
    System.out.println(keyBytes.length); 

    Cipher cipher_RSA; 
    try { 
     cipher_RSA = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); 
     PublicKey pk = keyFactory.generatePublic(spec); 
     System.out.println(pk.getAlgorithm()+" format : "+pk.getFormat()); 

     cipher_RSA.init(Cipher.ENCRYPT_MODE, pk); 
     return cipher_RSA.doFinal(message); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | 
      BadPaddingException | InvalidKeyException | InvalidKeySpecException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return null; 
    } 

} 

public static byte[] decrypt(String rawKey ,byte[] message){ 
    String strippedKey=stripPrivateKey(rawKey); 

    byte[] keyBytes = Base64.getDecoder().decode(strippedKey); 
    System.out.println(keyBytes.length); 

    Cipher cipher_RSA; 
    try { 
     cipher_RSA = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); 
     PrivateKey pk = keyFactory.generatePrivate(spec); 
     System.out.println(pk.getAlgorithm()+" format : "+pk.getFormat()); 

     cipher_RSA.init(Cipher.DECRYPT_MODE, pk); 
     return cipher_RSA.doFinal(message); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | 
      BadPaddingException | InvalidKeyException | InvalidKeySpecException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     return null; 
    } 
} 
public static String stripKey(String key){ 
    key = key.replace("-----BEGIN RSA PUBLIC KEY-----\n", ""); 
    key = key.replace("-----END RSA PUBLIC KEY-----", ""); 
    key = key.replace("\n", ""); 
    return key; 
} 

public static String stripPrivateKey(String key){ 
    key = key.replace("-----BEGIN PRIVATE KEY-----", ""); 
    key = key.replace("-----END PRIVATE KEY-----", ""); 
    key = key.replace("\n", ""); 
    return key; 
} 


} 

私はので、私はこれが一致しないキーを使用して行うことであると信じて、私のactaulコードと、明らかに間違っている何かを見つけることができません。

また、ヘッダー/フッターが公開キーと秘密キーで異なっていることに気付きます。オンラインで見ると、これは公開鍵がPKCS#8形式であるためです。

パブリックキーをpkcs#8形式に変更する必要がありますか?もしそうなら、これを行う最も簡単な方法は何ですか?

上記の私有鍵から公開鍵(pkcs8形式)を抽出できるはずです。これは簡単にできますか?

答えて

2

有効な公開鍵を取得できる場合、その鍵はPKCS#8形式ではなく、Javaが予期しているようにX.509(SubjectPublicKeyInfo)形式になります。 しかし、公開鍵と秘密鍵は実際にではなく、と一致します。答えhereを使用して、秘密鍵ファイルから正しい公開鍵ファイルを作成することができます。


Javaは、直接CRTパラメータなしRSAPrivateKeyから公開指数を取得するためのコードが含まれていません。しかし、Javaのみのソリューションが必要な場合はPrivateKeyをさらにRSAPrivateCrtKeyにキャストして公開の指数を取得する方法が含まれています(getPublicExponent)。次に、RSA KeyFactoryを使用してRSAPublicKeySpecを使用して公開鍵を生成することができます。


また、PEMファイルを解析して、Javaの公開鍵を取得することもできます。 Bouncy Castle API。しかし、もしあなたがそうすれば急な学習曲線を期待してください。

+0

Jamesさんからupvote [この回答](https://stackoverflow.com/a/24768779/589259)を忘れないでください! –

関連する問題