2014-12-25 6 views
2

Я работаю над веб-приложением, и мне нужно поговорить с сервером в зашифрованном виде, используя открытый/закрытый ключ RSA. У меня есть открытый ключ в текстовом файле так:PHP RSA-открытый ключ base64 кодировка

¨Ì�sr�java.math.BigIntegerå¸ü©;˚�I�bitCountIbitLengthI�firstNonzeroByteNumI�lowestSetBitI�signum[ 
� magnitudet�[Bxr�java.lang.Numberܨïî‡ã��xpˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇ˛���ur�[B¨Û¯T‡��xp���ØÕ..˛¶⁄ 
[í'‰∑S~ÆhU‚Ãu|ˆ*Ÿ"E˝x©àÚ†qçÎU¬òü`Oˇ?{q^⁄/O'•à%œÍ¬S� ∏íU$0≥i‹Hï™è>æ∑÷é˜ FVÚµ™ŒR=*ÑπGF%À¨ËߥÀüm‡(T¨‘Pq.ã3ˇ∑Ò;ªmÔ˙ 
C–„¿ç5åÌŒææ°4ån”®Å–MAQ’kÜì∑ÊË°ÂÅíîc»AÈ� 
∫ıƒËv:eÚDÑØKv3Áq”cO´HÁzπ…ÅÔ©ˇwlWènö◊aAß° m͇ïöH˚Æ)˛WeŸci·JbÜ q˙H£xsq�~��ˇˇˇˇˇˇˇˇˇˇˇ˛ˇˇˇ˛���uq�~����≠íi5˛¸¥Q‚í(2ûfiΩL0ΩÅ≤ò` 
÷…7¯ú)K´ºÎW2j·°Ø«¨X”gºŸ«lÇ8øÃ√3RÕ·ƒŸÚ¢fl∆,flr’X∆È|˚ì[Nfl%≈Búp·≤∑◊gπrõà–À≠˛`»Á†U„«¨ë+e|üæÄ®iLˇ⁄q¨@ä;…gRî>òvû+…U^ËÕdT∫|≠˙N"#zßø⁄+Å2ï¢=Nûe≠D˙§∞7X≥QPZ(Û`Ã-àÙ√ÿ÷Û˘£5[ŒÂ◊�IÄfiV bf´ÄÍÚ∫ê!*Ô´õD »E˛˙úhiô{ì“åCZWœ-åWÊ6‘t·x 

Когда я пытаюсь base64 закодировать его результат:

rO0ABXNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIo3hzcQB+AAD///////////////7////+AAAAAXVxAH4ABAAAAQCtDpJpDDX+Bfy0UeIXkigNMp7evQ5MML2Bsphg1sk3+JwpS6u86wdXMmrhoa/HrFjTZ7zZx2yCOL8WzMMzUh3NGuHE2fKi3xrGLN9y1VjGHul8+5NbTt8lxUKccOGytwbXZ7lym4jQEsut/h5gyOcRoFXjHceskStlfJ++gKhpTP/acaxAijvJZ1IRlD6Ydp4ryQNVXujNZFS6fK36TiJ/I3qnvxfaK4EylaISPU6eZa1E+qSwN1gQs1FQWigQ82DMLYj0w9jW8/mjNRpbEs7l1wBJgN5WCWJmqweA6vK6kCEq76ubRAnIRf76nGhpmXuT0oxDEVpXzy2MV+Y21HTheA== 

, который всегда дает мне недействительный открытый ключ. Когда я пытаюсь:

openssl_public_encrypt($data, $encrypted_data, base64_encode($key), OPENSSL_PKCS1_PADDING); 

Я знаю, что открытый ключ должен начинаться с:

-----BEGIN PUBLIC KEY----- 

и заканчивая:

-----END PUBLIC KEY----- 

Я пытался использовать:

"-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($key)) . "\r\n-----END PUBLIC KEY-----"; 

, но он все еще не работает. Может ли кто-нибудь помочь?

+4

то, что вы говорите, что у вас есть «открытый ключ в текстовом файле», не выглядит так для меня. Пока вы не можете гарантировать, что это действительно ключ, все, что вы делаете с этим, будет ошибочным. Поэтому я бы предложил вам дважды проверить, что это действительно ключ, и если это ключ, как правильно извлечь его из двоичного файла. – hakre

+0

Можете ли вы получить копию этого ключа в формате ASCII? У них часто есть «ASCII armor» вокруг них, чтобы понять, что это за ключ. – halfer

+0

Я уверен, что это ключ, который был отправлен мне командой разработчиков моего клиента –

ответ

2

Вам понадобится Java-код для преобразования этих сериализованных значений BigInteger в закрытый ключ и открытый ключ. Бинарный код с кодировкой base64, по-видимому, содержит два сериализованных объекта BigInteger, модуль и частный экспонент (который теперь открыт). Чтобы получить кодировку PEM, лучше полагаться на замке Надувного сделать преобразование:

import java.io.BufferedInputStream; 
import java.io.ByteArrayInputStream; 
import java.io.ObjectInputStream; 
import java.io.PrintWriter; 
import java.math.BigInteger; 
import java.security.InvalidKeyException; 
import java.security.KeyFactory; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.Signature; 
import java.security.SignatureException; 
import java.security.spec.RSAPrivateKeySpec; 
import java.security.spec.RSAPublicKeySpec; 

import org.bouncycastle.openssl.PEMWriter; 
import org.bouncycastle.util.encoders.Base64; 

public class KeysFromSerializedBigIntegers { 

    private static final String FROM_QUESTION = "rO0ABXNyABRqYXZhLm1hdGguQmlnSW50ZWdlcoz8nx+pO/sdAwAGSQAIYml0Q291bnRJAAliaXRMZW5ndGhJABNmaXJzdE5vbnplcm9CeXRlTnVtSQAMbG93ZXN0U2V0Qml0SQAGc2lnbnVtWwAJbWFnbml0dWRldAACW0J4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHD///////////////7////+AAAAAXVyAAJbQqzzF/gGCFTgAgAAeHAAAAEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIo3hzcQB+AAD///////////////7////+AAAAAXVxAH4ABAAAAQCtDpJpDDX+Bfy0UeIXkigNMp7evQ5MML2Bsphg1sk3+JwpS6u86wdXMmrhoa/HrFjTZ7zZx2yCOL8WzMMzUh3NGuHE2fKi3xrGLN9y1VjGHul8+5NbTt8lxUKccOGytwbXZ7lym4jQEsut/h5gyOcRoFXjHceskStlfJ++gKhpTP/acaxAijvJZ1IRlD6Ydp4ryQNVXujNZFS6fK36TiJ/I3qnvxfaK4EylaISPU6eZa1E+qSwN1gQs1FQWigQ82DMLYj0w9jW8/mjNRpbEs7l1wBJgN5WCWJmqweA6vK6kCEq76ubRAnIRf76nGhpmXuT0oxDEVpXzy2MV+Y21HTheA=="; 

    public static void main(String[] args) throws Exception { 
     byte[] binary = Base64.decode(FROM_QUESTION); 
     ByteArrayInputStream bais = new ByteArrayInputStream(binary); 
     BufferedInputStream bis = new BufferedInputStream(bais, 16); 
     ObjectInputStream ois = new ObjectInputStream(bis); 

     BigInteger modulus = null; 
     BigInteger privExp = null; 
     while (true) { 
      bis.mark(16); 
      if (bis.read() == -1) { 
       bis.reset(); 
       break; 
      } 
      bis.reset(); 

      Object o = ois.readObject(); 
      if (o instanceof BigInteger) { 
       BigInteger bi = (BigInteger) o; 

       if (modulus == null) { 
        modulus = bi; 
       } else if (privExp == null) { 
        privExp = bi; 
       } 
      } 
     } 

     KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA"); 

     RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, 
       privExp); 
     PrivateKey privateKey = rsaKeyFactory 
       .generatePrivate(rsaPrivateKeySpec); 

     BigInteger guessedPubExp = BigInteger.valueOf(0x010001); 
     RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, 
       guessedPubExp); 
     PublicKey publicKey = rsaKeyFactory.generatePublic(rsaPublicKeySpec); 


     PEMWriter pemWriter = new PEMWriter(new PrintWriter(System.out)); 
     pemWriter.writeObject(privateKey); 
     pemWriter.writeObject(publicKey); 
     pemWriter.flush(); 

     test(privateKey, publicKey); 
    } 

    private static void test(PrivateKey privateKey, PublicKey publicKey) 
      throws NoSuchAlgorithmException, InvalidKeyException, 
      SignatureException { 
     Signature rsa = Signature.getInstance("SHA512withRSA"); 
     rsa.initSign(privateKey); 
     byte[] sig = rsa.sign(); 
     rsa.initVerify(publicKey); 
     boolean verified = rsa.verify(sig); 
     // prints true for this key pair 
     System.out.println(verified); 
    } 
} 

(примечание: это даже не соответствует моей собственной практике коды)

Который приведет:

-----BEGIN RSA PRIVATE KEY----- 
MIICHwIBAAKCAQEAr80ULi7+ptoVW5In5LdTfq5oVeLMdXwO9irZIkX9eKmI8qBx 
jetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrCUwAJA7iSVQEYAyQwF7Np3BRIlaqP 
Pr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TLn23gKFSs1FBxGi6LCjMe/7fxO7tt 
7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQTUFR1WuGk7fm6KHlgZIelAsWY8hB 
6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZSOd6ucmBGu+p/3dsV49umtdhQacC 
ocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpIowIBAAKCAQEArQ6SaQw1/gX8tFHi 
F5IoDTKe3r0OTDC9gbKYYNbJN/icKUurvOsHVzJq4aGvx6xY02e82cdsgji/FszD 
M1IdzRrhxNnyot8axizfctVYxh7pfPuTW07fJcVCnHDhsrcG12e5cpuI0BLLrf4e 
YMjnEaBV4x3HrJErZXyfvoCoaUz/2nGsQIo7yWdSEZQ+mHaeK8kDVV7ozWRUunyt 
+k4ifyN6p78X2iuBMpWiEj1OnmWtRPqksDdYELNRUFooEPNgzC2I9MPY1vP5ozUa 
WxLO5dcASYDeVgliZqsHgOryupAhKu+rm0QJyEX++pxoaZl7k9KMQxFaV88tjFfm 
NtR04QIBAAIBAAIBAAIBAAIBAA== 
-----END RSA PRIVATE KEY----- 
-----BEGIN PUBLIC KEY----- 
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr80ULi7+ptoVW5In5LdT 
fq5oVeLMdXwO9irZIkX9eKmI8qBxjetVwpifYE8M/z8ee3Fe2i9PJ6WIJQ/PHOrC 
UwAJA7iSVQEYAyQwF7Np3BRIlaqPPr631o73IEZW8rWqzlI9KoS5R0Yly6zop7TL 
n23gKFSs1FBxGi6LCjMe/7fxO7tt7/p/AUPQ48CNNYzGCu3Ovr6hNIxuBBzTqIHQ 
TUFR1WuGk7fm6KHlgZIelAsWY8hB6QC6B3/1xALodjpl8kSErwRLdjPncdNjT6sZ 
SOd6ucmBGu+p/3dsV49umtdhQacCocpt6uCVmkgM+64p/ldl2WMSaeFKYoYgcfpI 
owIDAQAB 
-----END PUBLIC KEY----- 
Verification: true 

Итак, у вас есть пара ключей RSA 2048 бит минус параметры CRT. Обратите внимание, что другая сторона должна, по крайней мере, использовать RSAPrivateKey.getEncoded() и RSAPublicKey.getEncoded() вместо сериализации объектов.