Last active
October 27, 2015 08:04
-
-
Save kimutansk/5f3e18f7bb777b0f5b49 to your computer and use it in GitHub Desktop.
AWS IoTにJVM系言語(Scala)から接続するには(Publish) ref: http://qiita.com/kimutansk/items/2a4a7ce628fcd054342a
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# mosquitto_sub --cafile rootCA.pem --cert cert.pem --key private.pem -h ******.iot.ap-northeast-1.amazonaws.com -p 8883 -q 1 -d -t test-topic -i mosquitto-subscriber | |
Client mosquitto-subscriber sending CONNECT | |
Client mosquitto-subscriber received CONNACK | |
Client mosquitto-subscriber sending SUBSCRIBE (Mid: 1, Topic: test-topic, QoS: 1) | |
Client mosquitto-subscriber received SUBACK | |
Subscribed (mid: 1): 1 | |
Client mosquitto-subscriber received PUBLISH (d0, q1, r0, m1, 'test-topic', ... (12 bytes)) | |
Client mosquitto-subscriber sending PUBACK (Mid: 1) | |
Test Message |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.eclipse.paho.client.mqttv3.{MqttMessage, MqttConnectOptions, MqttClient} | |
/** MQTT Publish Test Class */ | |
object MqttPublisher { | |
def main(args: Array[String]) { | |
// Connect Target | |
val brokerURI:String = "ssl://******.iot.ap-northeast-1.amazonaws.com:8883" | |
// SocketFactoryGenerate | |
val socketFactory = SocketFactoryGenerator.generateFromFilePath("/etc/cert/rootCA.pem", "/etc/cert/cert.pem", "/etc/cert/private.pem", "password") | |
// MQTT Client generate | |
val client:MqttClient = new MqttClient(brokerURI, "mqtt-publisher") | |
client.setCallback(new PublishMqttCallback) | |
val options:MqttConnectOptions = new MqttConnectOptions() | |
options.setSocketFactory(socketFactory) | |
client.connect(options) | |
val message:MqttMessage = new MqttMessage("Test Message".getBytes("UTF-8")) | |
client.publish("test-topic", message) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.eclipse.paho.client.mqttv3.{IMqttDeliveryToken, MqttMessage, MqttCallback} | |
/** Publish MqttCallBack */ | |
class PublishMqttCallback extends MqttCallback{ | |
// Nop | |
override def deliveryComplete(iMqttDeliveryToken: IMqttDeliveryToken): Unit = ??? | |
override def messageArrived(s: String, mqttMessage: MqttMessage): Unit = ??? | |
override def connectionLost(throwable: Throwable): Unit = ??? | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.{ByteArrayInputStream, InputStream, InputStreamReader} | |
import java.nio.file.{Files, Paths} | |
import java.security.cert.{CertificateFactory, X509Certificate} | |
import java.security.{KeyPair, KeyStore, Security} | |
import javax.net.ssl.{KeyManagerFactory, SSLContext, SSLSocketFactory, TrustManagerFactory} | |
import org.bouncycastle.cert.X509CertificateHolder | |
import org.bouncycastle.jce.provider.BouncyCastleProvider | |
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter | |
import org.bouncycastle.openssl.{PEMKeyPair, PEMParser} | |
/** Factory for [[javax.net.ssl.SSLSocketFactory]] instances. */ | |
object SocketFactoryGenerator { | |
/** | |
* Generate [[javax.net.ssl.SSLSocketFactory]] from pem file paths. | |
* | |
* @param rootCaFilePath Root CA file path | |
* @param certFilePath Certificate file path | |
* @param keyFilePath Private key file path | |
* @return Generated [[javax.net.ssl.SSLSocketFactory]] | |
*/ | |
def generateFromFilePath(rootCaFilePath:String, certFilePath:String, keyFilePath:String, keyStorePassword:String):SSLSocketFactory = { | |
Security.addProvider(new BouncyCastleProvider()) | |
// load Root CA certificate | |
val rootCaParser:PEMParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(rootCaFilePath))))) | |
val rootCaCertHolder:X509CertificateHolder = rootCaParser.readObject().asInstanceOf[X509CertificateHolder] | |
val rootCaCert:X509Certificate = convertToJavaCertificate(rootCaCertHolder) | |
rootCaParser.close() | |
// load Server certificate | |
val certParser:PEMParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(certFilePath))))) | |
val serverCertHolder:X509CertificateHolder = certParser.readObject.asInstanceOf[X509CertificateHolder] | |
val serverCert:X509Certificate = convertToJavaCertificate(serverCertHolder) | |
certParser.close() | |
// load Private Key | |
val keyParser:PEMParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(Files.readAllBytes(Paths.get(keyFilePath))))) | |
val pemKeyPair:PEMKeyPair = keyParser.readObject.asInstanceOf[PEMKeyPair] | |
val keyPair:KeyPair = new JcaPEMKeyConverter().getKeyPair(pemKeyPair) | |
keyParser.close() | |
// Root CA certificate is used to authenticate server | |
val rootCAKeyStore:KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) | |
rootCAKeyStore.load(null, null) | |
rootCAKeyStore.setCertificateEntry("ca-certificate", convertToJavaCertificate(rootCaCertHolder)) | |
val tmf:TrustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) | |
tmf.init(rootCAKeyStore); | |
// client key and certificates are sent to server so it can authenticate us | |
val ks:KeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) | |
ks.load(null, null) | |
ks.setCertificateEntry("certificate", serverCert) | |
ks.setKeyEntry("private-key", keyPair.getPrivate(), keyStorePassword.toCharArray, Array(serverCert)) | |
val kmf:KeyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()) | |
kmf.init(ks, keyStorePassword.toCharArray()); | |
// finally, create SSL socket factory | |
val context:SSLContext = SSLContext.getInstance("TLSv1.2") | |
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null) | |
context.getSocketFactory() | |
} | |
def convertToJavaCertificate(certificateHolder:X509CertificateHolder):X509Certificate = { | |
val is:InputStream = new ByteArrayInputStream(certificateHolder.toASN1Structure.getEncoded); | |
try { | |
CertificateFactory.getInstance("X.509").generateCertificate(is).asInstanceOf[X509Certificate] | |
} finally is.close() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment