2012-06-20 10 views
7

Mevcut projem için PHP'den Java uygulamasına bir imza göndermem gerekiyor. Verilerimi imzalamak için şu anda Crypt/RSA kullanıyorum. SHA256withRSA PHP'nin oturum açma sorumluluğu JAVA'dan doğrulayın

test için Aşağıdaki kod ile sadece "abc" imza atıyorum:

$rsa = new Crypt_RSA(); 
$plaintext = 'abc'; 

    $rsa->loadKey("MIICXgIBAAKBgQDjh+hNsqJe566JO0Sg7Iq5H1AdkauACdd8QMLp9YNY0HPslVH0 
rXaOFo0zgH0Ktu/Ku3lS1lfxbFQAY8b6ywZKvu4eoxlnEwuBwy09CG+3ZiVLBjCj 
TZHA/KOkpVLa+tA6KsoP6zv/xI/ACkSCxPGR0q3SiRuhXV/6tacoKxUYnwIDAQAB 
AoGBAIC00GOjONYWmFRoglnFdHNjkx4m2KyE5LAUsi1GBBapU+nwTXvq47VcbGNF 
u3XkJaC4i9igBv86GApgZp5XWia86On/Lz9NR4fB2EFP6Ydy84GfCDNNvkism4BR 
aA+eYdNiQ3Wfyi98ZpUi+rPsoI6Cid4eSkCC4poTUaqzMkiBAkEA9Gn1oIlUEoVI 
q/u5Y9vflXRDt95AA9AokJkQj7XTNjsz8ypU8TO6D6ZykpcbK6zjU0UJsQiC3dKj 
AgmAR2VzYwJBAO5RETMAyDnR+5g+MtHpwGqGdY4dq0j4y4CsdtOYKWwSTh3VQy+C 
eghJoyPRfIpulw2Mk/l+occEI0ohJl0+UJUCQQDSZtjVLwMZwnUx4EvSw/ewL9sP 
0Jpo7evNtoaEQDEncUWiYeGnljDowg/FU6FHMtiq2TajmMEXdflvioBMdfAjAkEA 
3TB60SbJr/i4Fo6sJm5ZO8W+eAALiTf50VzBERTqZTb8L+5PZFoqn2SROV5mxClu 
o5G1idzBlHC/vD7WV7bNnQJAd0FrxaMBurJ4Uv/B8TDP+eeBdB7d9rKw0+TVlcel 
cbpIz6BIP6+nmsgy6dbDRnx0eC/MgF2EU0wrCu1DK0PyWA=="); 
    $rsa->setHash("sha256"); 
    $signature = $rsa->sign($plaintext); 

$signature_encoding = mb_convert_encoding($signature, "UTF-8"); 
    error_log("signature encoded in UTF-8 :" . $signature_encoding); 

    $encoded_sign = base64_encode($signature_encoding); 
    error_log("encoded sign for abc: " . $encoded_sign); 

ben php kodundan imzayı doğrulamak olabilir. Ama JAVA'dan doğrulamaya gelince, ben başarılı olamadım.

public boolean verify(String signed, String data, PubKey pubKey) throws Exception{ 

    PublicKey publicKey = jceProvider.generateRSAPublicKeyFromX509(
      base64.decode(pubKey.getEncodedKey()) 
    ); 

    byte[] signature = base64.decode(signed); 
    byte[] verifier = data.getBytes(Charset.forName("UTF-8")); 

    return jceProvider.verify(signature, verifier, publicKey); 

} 

public class JCEProvider { 

    public boolean verify (byte[] signature, byte[] verifier, PublicKey publicKey) throws Exception{ 

     Signature rsaSignature = Signature.getInstance("SHA256withRSA"); 

     rsaSignature.initVerify(publicKey); 
     rsaSignature.update(verifier); 

     return rsaSignature.verify(signature); 

    } 

Ben çünkü tuşlarının olduğunu sanmıyorum Daha önce söylediğim gibi ben zaten PHP onu doğrulayabilir: Burada doğrulamak işlemini yapar java kodudur. PHP kodlaması veya bayt akışları hakkında özlediğim bir şey var ama şimdilik anı kaybettim.

Herhangi bir yardım için teşekkür ederiz.

+0

görünüyor. Özel anahtarla doğrulamanız gerekiyor. – Polynomial

+0

teşekkürler @Polynomial ancak bu uzun dize özel anahtarım 1024 bayttır. – LostMohican

+2

Lütfen, * gerçek * private anahtarınızı StackOverflow'a göndermediğini söyleyin ... – Polynomial

cevap

5

. İşte benim çizgili aşağı örnekim. Herhangi bir karakter kodlamasından, satır bitiminden vb. Haberdar olun. Bu, metin verilerinizin değiştirilmiş ikili gösterimi ile sonuçlanır.

PHP RSA_SHA256-Burcu:

<?php 

$data = "For my current project I have to send a signature from PHP to Java application. I am using Crypt/RSA right now for signing my data."; 

$private_key = <<<EOD 
-----BEGIN RSA PRIVATE KEY----- 
MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z 
RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9 
sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R 
6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ 
h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n 
Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra 
I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI 
-----END RSA PRIVATE KEY----- 
EOD; 

$binary_signature = ""; 

$algo = "SHA256"; 
openssl_sign($data, $binary_signature, $private_key, $algo); 
print(base64_encode($binary_signature) ."\n"); 

?> 

ikili imza kodlanmış base64 çıktısı:

OnqiWnFQ2nAjOa1S57Du9jDpVr4Wp2nLdMk2FX +/QX1 + SAHpVsW1JvQYqQUDlxvbTOE9vg6dlU6i3omR7KipLw ==

java- RSA_SHA256-Doğrulama:.

import java.security.GeneralSecurityException; 
import java.security.KeyFactory; 
import java.security.PublicKey; 
import java.security.Signature; 
import java.security.spec.X509EncodedKeySpec; 

import org.apache.commons.codec.binary.Base64; 

public class RsaVerify { 

    public static void main(String args[]){ 
     String publicKey = 
//    "-----BEGIN PUBLIC KEY-----"+ 
       "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6"+ 
       "zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ=="; 
//    "-----END PUBLIC KEY-----"; 

     byte[] data = "For my current project I have to send a signature from PHP to Java application. I am using Crypt/RSA right now for signing my data.".getBytes(); 
     byte[] signature = Base64.decodeBase64("OnqiWnFQ2nAjOa1S57Du9jDpVr4Wp2nLdMk2FX+/qX1+SAHpVsW1JvQYqQUDlxvbTOE9vg6dlU6i3omR7KipLw=="); 

     try { 
      System.out.println(verify(data, signature, publicKey)); 
     } catch (GeneralSecurityException e) { 
      e.printStackTrace(); 
     } 

    } 

    private static boolean verify(byte[] data, byte[] signature, String publicKey) throws GeneralSecurityException{ 
     X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey)); 
     KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
     PublicKey pubKey = keyFactory.generatePublic(pubKeySpec); 
     Signature sig = Signature.getInstance("SHA256withRSA"); 
     sig.initVerify(pubKey); 
     sig.update(data); 
     return sig.verify(signature); 
    } 
} 
+0

teşekkürler @Sascha günümü kurtardınız :) .Sadece php'nin kendi kılavuzlarında SHA256'yı göremiyor musunuz? http://us3.php.net/manual/en/openssl.signature-algos.php – LostMohican

+1

Bugün, zaten yapabilirsiniz;) –

1

PHP çözümünüzü geliştirmeniz gerektiğini düşünüyorum. http://php.net/manual/en/function.openssl-get-md-methods.php göre ayrıca mümkün muhtemelen komut ile openssl çağrı PHP doğrudan [47] => sha256WithRSAEncryption kullanabilirsiniz: Zaten bahsedilen whity gibi openssl kullanıyorum

openssl dgst -sha256 -sign my.key -out in.txt.sha256 in.txt 
+0

teşekkürler @Whity ama sindirim yöntemine anahtar eklemek için herhangi bir yol bulamadık:/ – LostMohican

+0

http://stackoverflow.com/questions/10524198/what-version-of-openssl-is-needed-to-sign -with-sha256withrsaencryption –

3

phpseclib, varsayılan olarak daha güvenli PSS dolgu kullanır. Java muhtemelen PKCS # 1 dolgu kullanıyor. Eğer (Ben yapıyor tavsiye ederim) phpseclib rota gitmek için eğer öyleyse ... bunu: Eğer ortak anahtar ile doğrulanması sonra, genel anahtar ile oturum açtığınız

$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); 
+0

Neden bilmiyorum ama her seferinde phpseclib s işareti sonucu değiştirdim! – LostMohican

+0

İmza modu CRYPT_RSA_SIGNATURE_PKCS1 olarak ayarlandığında onlar benim için uygun. Varsayılan imza modunu kullanarak eşleşmezler, ancak bu modun rasgele doldurulmuş olması nedeniyle. –