2012-07-03 7 views
8

Я пытаюсь связаться с сервером через SSL. Клиентский файл PEM состоит из сертификата и секретного ключа rsa.Flash SecureSocket и закрытый ключ RSA

Мне удалось преобразовать как сертификат, так и ключ в двоичный DER. Я успешно загружаю сертификат DER в SecureSocket (с функцией addBinaryChainBuildingCertificate), но когда я пытаюсь подключиться к серверу, я получаю ошибку «главного несоответствия». Если я попытаюсь использовать вышеупомянутую функцию для загрузки ключа DER, я получаю ошибку «неправильного параметра».

Я предполагаю, что «основное несоответствие» связано с тем, что я не загрузил закрытый ключ. Но я не вижу никакой функции для загрузки ключа RSA в SecureSocket. Есть ли какие-либо решения? Нужно ли мне связываться с сервером только с сертификатом, но удалять ключ из уравнения?

EDIT:

Код:

package { 

    import flash.display.Sprite; 
    import flash.net.SecureSocket; 
    import flash.net.URLLoader; 
    import flash.events.ProgressEvent; 
    import flash.events.Event; 
    import flash.events.IOErrorEvent; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
    import flash.utils.ByteArray; 

    public class TestSSL2 extends Sprite { 

     private var mSocket:SecureSocket = new SecureSocket(); 

     private var certFile:String = "ca.der"; 
     private var keyFile:String = "key.der"; 

     private var cert:ByteArray; 
     private var key:ByteArray; 

     public function TestSSL2() { 
      trace("SecureSocket.isSupported",SecureSocket.isSupported); 

      var urlLoader:URLLoader = new URLLoader(); 
      urlLoader.addEventListener(Event.COMPLETE, certLoaded, false, 0, true); 
      urlLoader.dataFormat = URLLoaderDataFormat.BINARY; 
      urlLoader.load(new URLRequest(certFile)); 
     } 
     private function certLoaded(e:Event):void { 
      cert = (e.target as URLLoader).data; 
      trace("certificate",cert.length); 
      mSocket.addBinaryChainBuildingCertificate(cert, true); 

      var urlLoader:URLLoader = new URLLoader(); 
      urlLoader.addEventListener(Event.COMPLETE, keyLoaded, false, 0, true); 
      urlLoader.dataFormat = URLLoaderDataFormat.BINARY; 
      urlLoader.load(new URLRequest(keyFile)); 
     } 
     private function keyLoaded(e:Event):void { 
      key = (e.target as URLLoader).data; 
      trace("key",key.length); 
      mSocket.addBinaryChainBuildingCertificate(key, true); 

      mSocket.connect("127.0.0.1", 3000); 
      mSocket.addEventListener(Event.CONNECT, socketConnected); 
      mSocket.addEventListener(IOErrorEvent.IO_ERROR, onError); 
      mSocket.addEventListener(ProgressEvent.SOCKET_DATA, socketData); 
     } 

     private function onError(error:IOErrorEvent):void { 
      trace("ERROR!",error.text,":",mSocket.serverCertificateStatus); 
     } 

     private function socketConnected(e:Event):void { 
      trace("Connected", e); 
     } 

     private function socketData(e:*):void { 
      var data:String; 
      data = mSocket.readUTFBytes(mSocket.bytesAvailable); 
      trace(data); 
     } 
    } 

} 

Результат:

SecureSocket.isSupported true 
certificate 497 
key 607 
ArgumentError: Error #2004: One of the parameters is invalid. 
    at flash.net::SecureSocket/addBinaryChainBuildingCertificate() 
    at TestSSL2/keyLoaded() 
    at flash.events::EventDispatcher/dispatchEventFunction() 
    at flash.events::EventDispatcher/dispatchEvent() 
    at flash.net::URLLoader/onComplete() 

Если я комментирую строку:

//mSocket.addBinaryChainBuildingCertificate(key, true);

я получаю:

SecureSocket.isSupported true 
certificate 497 
key 607 
ERROR! Error #2031: Socket Error. URL: 127.0.0.1 : principalMismatch 
+1

Сертификаты загружаются и проверяются, когда вы выполняете функцию socket.connect? Помимо этого я не могу помочь, поскольку вы не отправляли код и не указывали конкретные коды ошибок. –

+0

Добавлено, но не может понять, как это может помочь :-(Позвольте мне добавить, что локальный сервер отлично работает с локальным клиентом C++, который считывает сертификат и ключ из файла pem. –

+0

Вы запускаете SWF локально или тестируется, развернуто в сети? –

ответ

3

Во-первых:

«Главный рассогласование» указывает, что общее имя сертификата на защищенном сервере не соответствует имени DNS, который вы подключаетесь.

Учитывая, что вы подключаетесь к localhost (127.0.0.1), наверняка будет несоответствие. Флеш-сокеты особенно строги, когда речь идет о безопасных соединениях, и нет механизма для переопределения функций безопасности, в отличие от других сред выполнения (например, .NET и Java). Следующее должно быть истинным:

  1. общее имя сертификата месиво совпадает с именем DNS (есть релаксация здесь «звезда» сертификаты т.е. серт для *.bob.com считается действительным для mr.bob.com)
  2. сертификат должен быть действует в отношении срока и доверия цепи

во-вторых:

Вы, кажется, есть неправильное представление о том, как сертификаты работы. Вам не нужно добавлять сертификаты с помощью метода addBinaryChainBuildingCertificate(), если сертификат сервера выдается доверенным корневым центром, то есть сертификат, который подписывает сертификат сервера, находится в локальном хранилище доверия целевого устройства.

Для иллюстрации:

  • У меня есть сертификат на this.is.awesome.com установлен на моем сервере и запись DNS, устраняющее this.is.awesome.com на IP-адрес моего сервера
  • Этот сертификат выдается органом сертификации Доверьте L1C.
  • Сертификат L1C, в свою очередь, выдается авторитетом root Entrust 2048.

На моем компьютере у меня есть полномочный орган Entrust 2048 Root, установленный в моем хранилище доверенных корневых сертификатов. Однако у меня нет установленного сертификата L1C. Когда я пытаюсь подключиться к this.is.awesome.com, подключение завершится неудачно, так как сертификат сервера не может быть проверен против авторитета L1C.

Если я добавлю сертификат L1C, закодированный DER, используя addBinaryChainBuildingCertificate(), соединение будет успешным. Сертификат сервера будет проверен на соответствие сертификату L1C, который, в свою очередь, будет проверен против корневого сертификата 2048, который является доверенным корнем.

Резюмируя:

Ваши вопросы подключения, кажется, происходят от вашей попытки подключения к локальной машине. Попробуйте добавить запись в ваш файл HOSTS, который сопоставляет имя вашего сертификата с 127.0.0.1 и затем соединяется с этим именем. Если это не удается проверить цепь эмитента на вашем сертификате и добавить цепочку эмитентов, позвонив по номеру addBinaryChainBuildingCertificate() один раз для каждого сертификата выдачи в цепочке. Окончательный или корневой сертификат следует пометить как таковой, передав true, поскольку второй параметр равен addBinaryChainBuildingCertificate()

Смежные вопросы