SSL
官方地址:http://www.rabbitmq.com/ssl.html
百科:
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。
分为 单向认证 和 双向认证。RabbitMQ 采用的是双向认证方式。
一、配置过程:
# mkdir testca # cd testca # mkdir certs private # chmod 700 private # echo 01 > serial # touch index.txt
下面这段保存成 openssl.cnf 文件
[ ca ] default_ca = testca [ testca ] dir = . certificate = $dir/cacert.pem database = $dir/index.txt new_certs_dir = $dir/certs private_key = $dir/private/cakey.pem serial = $dir/serial default_crl_days = 7 default_days = 365 default_md = sha256 policy = testca_policy x509_extensions = certificate_extensions [ testca_policy ] commonName = supplied stateOrProvinceName = optional countryName = optional emailAddress = optional organizationName = optional organizationalUnitName = optional domainComponent = optional [ certificate_extensions ] basicConstraints = CA:false [ req ] default_bits = 2048 default_keyfile = ./private/cakey.pem default_md = sha256 prompt = yes distinguished_name = root_ca_distinguished_name x509_extensions = root_ca_extensions [ root_ca_distinguished_name ] commonName = hostname [ root_ca_extensions ] basicConstraints = CA:true keyUsage = keyCertSign, cRLSign [ client_ca_extensions ] basicConstraints = CA:false keyUsage = digitalSignature extendedKeyUsage = 1.3.6.1.5.5.7.3.2 [ server_ca_extensions ] basicConstraints = CA:false keyUsage = keyEncipherment extendedKeyUsage = 1.3.6.1.5.5.7.3.1
自己颁发给自己的 ca 证书
# openssl req -x509 -config openssl.cnf -newkey rsa:2048 -days 365 -out cacert.pem -outform PEM -subj /CN=MyTestCA/ -nodes # openssl x509 -in cacert.pem -out cacert.cer -outform DER
服务器 证书
# cd .. # ls testca # mkdir server # cd server # openssl genrsa -out key.pem 2048 # openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=server/ -nodes # cd ../testca # openssl ca -config openssl.cnf -in ../server/req.pem -out ../server/cert.pem -notext -batch -extensions server_ca_extensions # cd ../server # openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword
客户端 证书
# cd .. # ls server testca # mkdir client # cd client # openssl genrsa -out key.pem 2048 # openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=client/ -nodes # cd ../testca # openssl ca -config openssl.cnf -in ../client/req.pem -out ../client/cert.pem -notext -batch -extensions client_ca_extensions # cd ../client # openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword
将 testca/cacert.pem、server/cert.pem、server/key.pem 复制到 /etc/rabbitmq/ssl/ 目录下面,记得查看权限,否则报 read timeout 异常
添加配置文件
二、java代码测试
cmd命令:
C:\Program Files\Java\jdk1.8.0_25>keytool -import -alias server1 -file D:\openssl\bin\server\cert.pem -keystore D:\openssl\bin\server\rabbitstore
项目截图:(拷贝 client/keycert.p12 和 rabbitstore 到项目中)
import java.io.FileInputStream; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.GetResponse; public class Example2 { public static void main(String[] args) throws Exception { char[] keyPassphrase = "MySecretPassword".toCharArray(); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(Class.class.getResource("/").getPath() + "keycert.p12"), keyPassphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, keyPassphrase); char[] trustPassphrase = "rabbitstore".toCharArray(); KeyStore tks = KeyStore.getInstance("JKS"); tks.load(new FileInputStream(Class.class.getResource("/").getPath() + "rabbitstore"), trustPassphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(tks); SSLContext c = SSLContext.getInstance("TLSv1.1"); c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); ConnectionFactory factory = new ConnectionFactory(); factory.setHost(""); factory.setPort(5671); factory.setUsername(""); factory.setPassword(""); factory.useSslProtocol(c); Connection conn = factory.newConnection(); Channel channel = conn.createChannel(); channel.queueDeclare("rabbitmq-java-test", false, true, true, null); channel.basicPublish("", "rabbitmq-java-test", null, "Hello, World".getBytes()); GetResponse chResponse = channel.basicGet("rabbitmq-java-test", false); if(chResponse == null) { System.out.println("No message retrieved"); } else { byte[] body = chResponse.getBody(); System.out.println("Recieved: " + new String(body)); } channel.close(); conn.close(); } }
结果:
三、c#代码测试
导入自颁发证书
using RabbitMQ.Client; using RabbitMQ.Util; using System; using System.Net.Security; using System.Text; namespace TestSSL { class Program { public static void Main(string[] args) { try { ConnectionFactory cf = new ConnectionFactory() { HostName = "", Port = 5671, UserName = "", Password = "" }; cf.Ssl.ServerName = "10-10-43-207"; //必须同服务器证书中设置的 CN 名称一致 cf.Ssl.CertPath = AppDomain.CurrentDomain.BaseDirectory + "client\\keycert.p12"; cf.Ssl.CertPassphrase = "MySecretPassword"; cf.Ssl.AcceptablePolicyErrors = //SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateNotAvailable | SslPolicyErrors.RemoteCertificateChainErrors; cf.Ssl.Enabled = true; using (IConnection conn = cf.CreateConnection()) { using (IModel ch = conn.CreateModel()) { ch.QueueDeclare("rabbitmq-dotnet-test", false, false, false, null); ch.BasicPublish("", "rabbitmq-dotnet-test", null, Encoding.UTF8.GetBytes("Hello, World")); BasicGetResult result = ch.BasicGet("rabbitmq-dotnet-test", true); if (result == null) { Console.WriteLine("No message received."); } else { Console.WriteLine("Received:"); DebugUtil.DumpProperties(result, Console.Out, 0); } ch.QueueDelete("rabbitmq-dotnet-test"); } } } catch (Exception ex) { Console.WriteLine(ex.InnerException); } Console.ReadKey(true); } } }
结果:
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/tq1226112215/
欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。