$x = &$y['z'];
также имеет эффект создания $y['z']
, если он не существует, и установите его на null
.
Это предотвращает сообщения об ошибках, которые вы, возможно, хотели прочитать. Я еще не нашел документацию по этому поводу; возможно, новый в 5.3, насколько мне известно.
Шаг 1: Создание самозаверяющего сертификата:
Я использовал этот код для генерации файла сертификата .pfx:
byte[] c = Certificate.CreateSelfSignCertificatePfx(
"CN=yourhostname.com", //host name
DateTime.Parse("2000-01-01"), //not valid before
DateTime.Parse("2010-01-01"), //not valid after
"mypassword"); //password to encrypt key file
using (BinaryWriter binWriter = new BinaryWriter(
File.Open(@"testcert.pfx", FileMode.Create)))
{
binWriter.Write(c);
}
Шаг 2: Загрузка сертификата
X509Certificate cert = new X509Certificate2(
@"testcert.pfx",
"mypassword");
Шаг 3: Собираем его вместе
Я заменил эту строку в файле Server Program.cs строкой из шага 2:
X509Certificate cert = getServerCert ();
В файл Client Program.cs, убедитесь, что вы установили serverName = yourhostname.com (и что он соответствует имени в сертификате)
Шаг 4: Аутентификация клиента
Вот как аутентифицируется мой клиент (он немного отличается от сервера):
TcpClient client = new TcpClient();
client.Connect(hostName, port);
SslStream sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(CertificateValidationCallback),
new LocalCertificateSelectionCallback(CertificateSelectionCallback));
bool authenticationPassed = true;
try
{
string serverName = System.Environment.MachineName;
X509Certificate cert = GetServerCert(SERVER_CERT_FILENAME, SERVER_CERT_PASSWORD);
X509CertificateCollection certs = new X509CertificateCollection();
certs.Add(cert);
sslStream.AuthenticateAsClient(
serverName,
certs,
SslProtocols.Default,
false); // check cert revokation
}
catch (AuthenticationException)
{
authenticationPassed = false;
}
if (authenticationPassed)
{
//do stuff
}
CertificateValidationCallback так же, как в случае с сервером, но обратите внимание, как AuthenticateAsClient принимает набор сертификатов, а не только один сертификат. Итак, вы должны добавить LocalCertificateSelectionCallback, например, так (в этом случае у меня есть только один сертификат клиента, поэтому я просто возвращаю первый в коллекции):
static X509Certificate CertificateSelectionCallback(object sender,
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
{
return localCertificates[0];
}
Вы также можете посмотреть этот пример. Пример реализации асинхронного клиента / сервера SslStream http://blogs.msdn.com/joncole/archive/2007/06/13/sample-asynchronous-sslstream-client-server-implementation .aspx
, если сертификат выдан неправильно, вы можете получить исключение. Серверный режим SSL должен использовать сертификат со связанным закрытым ключом.
пример базового сертификата
makecert -sr LocalMachine -ss My -n CN = тест -sky exchange -sk 123456
или
как внешний файл
makecert -sr LocalMachine -ss My -n CN = Test -sky exchange -sk 123456 c: \ Test.cer
Средство создания сертификатов (Makecert.exe)
http : //msdn.microsoft.com/en-us/library/bfsktky3%28VS.80%29.aspx
То, что вы предлагаете, звучит хорошо для меня, за исключением того, что кажется, что вы ждете, пока не будет вызван обратный вызов для генерации сертификата. Я не думаю, что это будет летать; AFAIK, вы должны предоставить действительный сертификат при вызове AuthenticateAsX
.
Тем не менее, эти классы являются переопределенными; Таким образом, теоретически вы можете создать производный класс, который сначала проверяет, нужно ли генерировать сертификат, генерирует его при необходимости, а затем вызывает метод parent AuthenticateAsX
.