{"id":34737819,"url":"https://github.com/rethab/php-stomp-cert-example","last_synced_at":"2026-05-26T10:32:11.555Z","repository":{"id":15026944,"uuid":"17752711","full_name":"rethab/php-stomp-cert-example","owner":"rethab","description":"An example project demonstrating the PHP Stomp library with SSL Certificates","archived":false,"fork":false,"pushed_at":"2015-05-11T13:46:17.000Z","size":688,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-12-26T14:41:21.109Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rethab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-14T16:37:27.000Z","updated_at":"2014-05-23T13:12:10.000Z","dependencies_parsed_at":"2022-09-19T11:22:35.514Z","dependency_job_id":null,"html_url":"https://github.com/rethab/php-stomp-cert-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rethab/php-stomp-cert-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rethab%2Fphp-stomp-cert-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rethab%2Fphp-stomp-cert-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rethab%2Fphp-stomp-cert-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rethab%2Fphp-stomp-cert-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rethab","download_url":"https://codeload.github.com/rethab/php-stomp-cert-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rethab%2Fphp-stomp-cert-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33517111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T03:12:49.672Z","status":"ssl_error","status_checked_at":"2026-05-26T03:12:47.976Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-25T03:43:59.060Z","updated_at":"2026-05-26T10:32:11.543Z","avatar_url":"https://github.com/rethab.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Prettier version of this page: http://rethab.github.io/php-stomp-cert-example\n\nphp-stomp-cert-example\n======================\n\nAn example project demonstrating the PHP Stomp library with SSL Certificates\n\nThe current version of the PHP Stomp library uses the function fsockopen, which\nmakes it impossible to send a certificate. On top of that, PHP does not verify\ncertificates of peers by default in versions before PHP 5.6.\n\nThis project aims to demonstrate how a modified version of the PHP Stomp library\nmay be used to communicate securely with a message broker. As an example,\nActiveMQ has been used, but this would really work with any broker that supports\nStomp.\n\nBy securely, I mean the client verifies the certificate of the server. And, a\nclient certificate is used for authentication.\n\n\n## Related Linkes\n* PHP TLS Peer Verification RFC: https://wiki.php.net/rfc/tls-peer-verification\n* ActiveMQ Documentation: http://activemq.apache.org/getting-started.html\n\n## Step by Step\n\n### Active MQ Certificate\n1. Download ActiveMQ from the official website and unpack it\n2. Delete the original keystore and truststore (conf/broker.{k,t}s)\n3. Create a new Keystore with a key using keytool (comes with JDK)\n   1. `keytool -genkey -keyalg RSA -alias broker -keystore broker.ks -validity 365 -keysize 2048`\n4. Set it in the activemq config (conf/activemq.xml). The truststore is\n   configured here as well. We are going to create it with the client\n   certificate though.\n    ```\u003csslContext\u003e\n           \u003csslContext keyStore=\"file:${activemq.base}/conf/broker.ks/\"\n            keyStorePassword=\"broker\"\n            trustStore=\"file:${activemq.base}/conf/broker.ts/\"\n            trustStorePassword=\"broker\" /\u003e\n       \u003c/sslContext\u003e\n    ```\n\n### PHP Client Certificate\n1. Create a keypair for the client\n   * `openssl genrsa -des3 -out php-client.key 2048`\n2. Create a signing request\n   * `openssl req -new -key php-client.key -out php-client.csr`\n3. We remove the password from the client for convenience. We could have left it\n   encrypted and tell PHP the password with the ssl context parameters.\n   * `openssl rsa -in php-client.key -out php-client.key`\n4. Self-sign the certificate signing request (the CSR is not required anymore after this step)\n   * `openssl x509 -req -days 365 -in php-client.csr -signkey php-client.key -out php-client.crt`\n5. The following command imports the certificate of the php-client into the\n   broker's truststore. It is perfectly fine to use an existing keystore, but\n   you might want to have control over whom you trust and therefore create a new\n   one. If the specified truststore does not exist, it is created (it will thus\n   ask you for a password).\n   * `keytool -import -file php-client.crt -alias php-client -keystore path/to/activemq/conf/broker.ts`\n\n### ActiveMQ Configuration\n1. First of all, we need to tell ActiveMQ that we are going to authenticate users\n   based on their certificate. Although topics (and queues) are created lazily,\n   we want to authorize the groups to read and/or write on certain queues rather\n   than just granting global write access. The following configuration snipped\n   tells it to use the users.properties and groups.properties in combination\n   with certificates. Place this in login.config:\n    ```\n    activemq-certificate {\n        org.apache.activemq.jaas.TextFileCertificateLoginModule\n            required\n            org.apache.activemq.jaas.textfiledn.user=\"users.properties\"\n            org.apache.activemq.jaas.textfiledn.group=\"groups.properties\";\n    };\n    ```\n2. Next up, let us map the certificate information to a username. The following\n   line ought to be placed in the file users.properties and tells ActiveMQ to\n   map a request with the following certificate information to the user php-client.\n   Note that not just anybody could send a certificate with this information,\n   since we imported the certificate into the truststore beforehand and only that\n   one will be accepted.\n    `php-client=CN=PHP Test, OU=Engineering, O=Company Test, L=Location Test, ST=State Test, C=US`\n3. ActiveMQ gives permissions on topics and queues to groups, which is why we\n   also need to create a group for our new user. The following line adds our\n   user php-client to the group php-client. Note that, if the group should have\n   more than one user, separate them with a comma. gropus.properties:\n    `php-client=php-client`\n4. We now tell ActiveMQ to use the configuration 'activemq-certificate' (as\n   defined in login.config) with the 'jaasCertificateAuthenticationPlugin' and\n   then setup the authorizationMap. We basically allow our members of the group\n   php-client to create the queue (admin), because we will create it when we\n   send the first message, and members of the group php-client are allowed to\n   write to it. Besides, we also need to grant the php-client group admin\n   privileges on the advisory topics ('\u003e' is a wildcard). Read more about\n   advisory topics in the ActiveMQ manual.\n    ```\n    \u003cplugins\u003e\n        \u003cjaasCertificateAuthenticationPlugin configuration=\"activemq-certificate\"/\u003e\n        \u003cauthorizationPlugin\u003e\n            \u003cmap\u003e\n                \u003cauthorizationMap\u003e\n                    \u003cauthorizationEntries\u003e\n                        \u003cauthorizationEntry topic=\"TestQueue\" admin=\"php-client\" write=\"php-client\" /\u003e\n                        \u003cauthorizationEntry topic=\"ActiveMQ.Advisory.\u003e\" admin=\"php-client\" /\u003e\n                    \u003c/authorizationEntries\u003e\n                \u003c/authorizationMap\u003e\n            \u003c/map\u003e\n        \u003c/authorizationPlugin\u003e\n    \u003c/plugins\u003e\n    ```\n5. Finally, we configure the stomp connect in the activemq.xml accordingly.\n   Suffix the URI part of the transport connector entry scheme with '+ssl' and add a\n   needClientAuth to the parameters of the URI such that it now looks like this:\n   `\u003ctransportConnector name=\"stomp\" uri=\"stomp+ssl://0.0.0.0:61613?needClientAuth=true\u0026amp;maximumConnections=1000\u0026amp;wireFormat.maxFrameSize=104857600\"/\u003e`\n\n### PHP Client Code\nNow that we have both the certificate of ActiveMQ (the only one we are going to\naccept as our peer) as well as a certificate we are going to use on the client\nside (and ActiveMQ knows about it by means of the trust store), we can put\ntogether the client side code to send a message to ActiveMQ from PHP.\n1. PHP needs a concatenanted file starting with the private key\n   followed by the certificate. Note that if you have a certificate hierarchy, all intermediate\n   certificates including the root CA itself must be part of this file as well.\n   * `cat php-client.key php-client.crt \u003e php-client-chain.pem`\n   * Or, alternatively (with intermediate certificates):\n         `cat php-client.key php-client.crt intermediate.crt rootca.crt \u003e php-client-chain.pem`\n2. We use the certficate of the broker directly from the PHP side rather than\n   using a common CA. For that, we need to export the certificate in the correct\n   format from the broker's keystore (note the '-rfc' option):\n   `keytool -export -rfc -alias broker.ks -keystore conf/broker.ks file broker.crt`\n3. Now we can pass these two files as ssl context parameters to stomp using the\n   following array:\n   ```\n   $opts = array(\n        'ssl' =\u003e array(\n            'local_cert' =\u003e './php-client-chain.pem',\n            'cafile' =\u003e './broker.crt',\n            'verify_peer' =\u003e true,\n        )\n    );\n   ```\n4. Finally, we can send the message to stomp:\n   ```\n   $con = new FuseSource\\Stomp\\Stomp('ssl://localhost:61613', $opts);\n   $con-\u003econnect();\n\n   $body = json_encode(array('message' =\u003e array('content' =\u003e 'hello, world')));\n   $headers = array('persistent' =\u003e 'true');\n   var_dump($con-\u003esend('/topic/TestQueue', $body, $headers));\n   ```\n\n## Debugging\n- Connect to the server and get the server certificate chain as well as the\n  potentially accepted certificates from a client. You should see the\n  certificate your previously put into the truststore:\n  `openssl s_client -connect localhost:61613 -cert php-client-chain.pem -debug -showcerts`\n- Is the certficiate in the correct format? Try to parse it with the following\n  two functions and look at the output (with, e.g. var_dump):\n  `openssl_x509_parse(file_get_contents('./file.crt'))`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frethab%2Fphp-stomp-cert-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frethab%2Fphp-stomp-cert-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frethab%2Fphp-stomp-cert-example/lists"}