En la majoria d'ocasions, els usuaris demanen un formulari de contacte a la seva web. En la majoria d'ocasions, també, s'acaben queixant de la quantitat d'spam que reben.
La primera pregunta que se'm passa pel cap és, i per què no donar un correu electrònic? I la resposta més habitual és, per evitar l'spam. És això cert? Evitem així l'spam? No i no.
Aquest seria un formulari de lliure accés per a visitants. Es compon d'un cert nombre de camps, el valor dels quals s'envia per correu a l'adreça internament configurada. Els principals punts en contra d'aquests formularis són:
Sí, es pot fer. De fet, molts servidors ja el tenen instal·lat pel correu entrant. El que estaríem fent és el mateix que faria el nostre servidor de correu quan rep aquest: decidir si passar-ho a la carpeta de brossa. En curt, repetiríem la feina dues vegades per cap motiu raonable.
Els Captcha no són realment filtres d'spam. El que fan és controlar que qui omple el formulari és un humà o un robot (un programa que repetitivament omple i envia). És un pedaç, no una solució.
Posar una adreça de correu electrònic a la web. Amb l'hiperenllaç que permeti fer clic i enviar, si es vol. Així de simple. I amb una llista de motius:
N'hi ha més, però serien tecnicismes al voltant del que ja hem dit.
En aquest repàs no ho tinc en compte tot, ni poso especial interès en l'ordre cronològic. Tampoc afecta en res el que veuràs.
Totes aquestes novetats, com tota la resta, incloses en l'estàndard. Sota codi font obert i completament gratuïtes.
Tot i no haver publicat massa cosa, ja veieu que aquí no es para. Els temps demanen això i més.
This 2018 I needed to install an SSL Certificate for a web application. Since Tomcat 9 features virtual hosted web application with differentiated SSL hosts, the next step were easy to guess: move to Java 10 plus Tomcat 9 and make use of these new features. This article goes about the process to its final ending, this web site.
Java 9 and above no longer include JAXB. Simply add the JAXB library to Tomcat 9.
Tomcat 9 no longer put the final slash to the URL (does not redirect). Modify conf/context.xml
to include mapper
attributes:
<Context ... mapperContextRootRedirectEnabled="true" mapperDirectoryRedirectEnabled="true"/>
If you already have a certificate you may want to skip this part. Otherwise, buy a certificate and continue.
First thing the provider ask for is a Certificate Signing Request. Lets generate one:
openssl req -new -newkey rsa:2048 -nodes -out [yourdomain].csr -keyout [yourdomain].key -subj "/C=[country]/ST=[state]/L=[city]/O=[organization]/OU=[department]/CN=[domain]"
Field |
Description |
yourdomain |
This will be the file name. For example www_domain_whatever, in my case |
country |
Two uppercase letters of your country, see ISO 3166-1. |
state |
Your state or province, as is. |
city |
Your city. |
organization |
Your organization name. |
department |
Department managing de certificate. |
domain |
As for Comodo Essential, the domain will apply to Recomendation: use |
Once executed, this command generated two files, yourdomain.csr
and yourdomain.key
. The CSR file is the Certificate Signing Request, and is the first thing you will need to provide when asking your certificate. The second is the Private Key. Keep them both in a secure place.
If everything has gone well, you now have a response from the Certification Provider and some certificates in you hard disk. Copy them where you saved previous generated files, CSR and private key. If you followed the instructions, you private key is stored in [yourdomain].key
file.
Now, one of the certificates you received is your certificate. The rest are called root certificate and chain certificates.
First thing we'll do is convert your private key and your certificate to PKCS12 format. Don't bother now as to why we use this format, I want a single keystore to include the whole bunch of certificates to simplify Tomcat configuration, and it turns out that Tomcat NIO likes this format. So, have it.
openssl pkcs12 -export -in [yourcertificate] -inkey [yourdomain].key -name [yourdomain] -out [yourdomain].p12
Field |
Description |
yourcertificate |
Your certificate is one of those the certification provider sent you. As for Comodo, my certificate was |
yourdomain |
This will be the file name. For example www_domain_whatever, in my case |
This step creates a new keystore file.
keytool -importkeystore -destkeypass [password] -destkeystore [yourdomain].keystore -srckeystore [yourdomain].p12 -srcstoretype PKCS12 -srcstorepass [password]
Now, add the root and chain certificates. Bellow the example with Comodo certificates. You may follow instructions provided for your own certificate provider. Notice that the only pattern used is alias equal to certificate file minus extension.
keytool -import -trustcacerts -alias AddTrustExternalCARoot -file AddTrustExternalCARoot.crt -keystore [yourdomain].keystore keytool -import -trustcacerts -alias COMODORSAAddTrustCA -file COMODORSAAddTrustCA.crt -keystore [yourdomain].keystore keytool -import -trustcacerts -alias COMODORSADomainValidationSecureServerCA -file COMODORSADomainValidationSecureServerCA.crt -keystore [yourdomain].keystore
If you followed the instructions, you have a keystore named [yourdomain].keystore
with everything required by Tomcat.
Let's explain something about Tomcat. Tomcat has a single Connector
for SSL configuration. Once you configure your keystore, it will be available by all the web application installed, but will only certificate your domain. So, where SSL hosting virtualization is?
Don't panic, there is SSL hosting virtualization. You achieve the goal by creating SSLHostConfig
elements with hostName
attribute set to match one of the Host
elements its name
attribute. One of them will need to be the defaultSSLHostConfigName
attribute in the Connector
element. Messy? See the server.xml
example with the values we used:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" defaultSSLHostConfigName="[domain]" ... > <SSLHostConfig hostName="[domain]"> <Certificate certificateKeystoreFile="[yourdomain].keystore" certificateKeystorePassword="[password]"/> </SSLHostConfig> .... </Connector> ... <Engine name="Catalina" defaultHost="[domain]"> <Host name="[domain]" appBase="/anyfolder" unpackWARs="false" autoDeploy="false"> </Host> ... </Engine>
Let's suppose we followed the steps with [domain2]
values. The server.xml
will look like:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" defaultSSLHostConfigName="[domain]" ... > <SSLHostConfig hostName="[domain]"> <Certificate certificateKeystoreFile="[yourdomain].keystore" certificateKeystorePassword="[password]"/> </SSLHostConfig> <SSLHostConfig hostName="[domain2]"> <Certificate certificateKeystoreFile="[yourdomain2].keystore" certificateKeystorePassword="[password2]"/> </SSLHostConfig> .... </Connector> ... <Engine name="Catalina" defaultHost="[domain]"> <Host name="[domain]" appBase="/anyfolder" unpackWARs="false" autoDeploy="false"> </Host> <Host name="[domain2]" appBase="/anyfolder2" unpackWARs="false" autoDeploy="false"> </Host> ... </Engine>
Now everything is more clear. [domain]
is the default SSL configuration, but when somebody visits [domain2]
there is a match between SSLHostConfig
its hostName
attribute and Host
its name
attribute. Thus, [yourdomain2].keystore
will be used.
Restart your Tomcat and... That's all!
Before start, I would like to mention Apache Tika and juniversalchardet. Tika is a full-featured file type detection library and, because so much features, takes a big amount of dependencies. I haven't tried juniversalchardet for does not detect ISO-8859-1
, which is the reason I needed charset detection.
Since none well suited my problem, I decided to detect charsets myself and, once results were in production, share it with anyone else. Hope you like it
Anyone developing web applications with data inputs and third-party frameworks, with a different charset than UTF-8
, might have encountered the need to auto-detect charset. Guessing the source of the input on utility classes, or passing the charset along among methods, doesn't seem to be the right way and isn't always possible.
We'll need a convert method, in order to change the string charset. The most simple way would be using String
supplied methods. Something like:
public String convert(String value, String fromEncoding, String toEncoding) { return new String(value.getBytes(fromEncoding), toEncoding); }
The problem remains, though. The variable fromEncoding
isn't always known.
Guessing? Well, let's be clear, we are guessing. Also taking some premises that might be not true. For instance, we probe using UTF-8
against a set of expected charsets. The good thing about it is that we know the elements at play and can change them at will.
The approach is very simple: if I do change the string from the expected charset to UTF-8
and then back from UTF-8
to the expected charset, shouldn't be the resulting string exactly the same than the original one?
Let's put this at work:
public static String charset(String value, String charsets[]) { String probe = StandardCharsets.UTF_8.name(); for(String c : charsets) { Charset charset = Charset.forName(c); if(charset != null) { if(value.equals(convert(convert(value, charset.name(), probe), probe, charset.name()))) { return c; } } } return StandardCharsets.UTF_8.name(); }
A possible call to the charset()
method would be:
String detectedCharset = charset(value, new String[] { "ISO-8859-1", "UTF-8" });
As I said, the approach uses the premise that UTF-8
will behave well on all transformations and that there is a reduced set of expected charsets. I haven't tried probing the whole Charset.availableCharsets()
. In case you do and find a better way, please let me know.
Aquests dies han estat tan elèctrics a Catalunya, que moltes persones s'han mostrat preocupades per la seguretat del seu sistema de missatgeria. Anem a donar una mirada ràpida als dos més utilitzats: WhatsApp i Telegram.
Mireu la data del text. Aquestes apps solen canviar sovint i el text no valdria per res.
WhatsApp entrega els missatges directament al receptor, sense que existeixin a cap servidor. Els servidors s'utilitzen exclusivament per resoldre el recipient del missatge (a qui s'envia).
Telegram, en canvi, utilitza els servidors per a fer l'enviament. El missatge, doncs, existeix al servidor.
WhatsApp encripta per defecte els xats normals, persona a persona. El missatge s'encripta al enviar i es desencripta al rebre.
Telegram envia el text com a text pla, sense encriptar.
WhatsApp encripta per defecte els xats de grup.
Telegram utilitza text pla.
WhatsApp no té xats privats com opció. Tots ho són.
Telegram encripta els xats privats, igualant-se així a WhatsApp, però amés ofereix configurar la durada del missatge. Els missatges s'esborren un cop passat el temps configurat.
Les còpies de seguretat són un dels problemes més complexes de resoldre. Es fan no encriptades i contenen tots els missatges rebuts. Els xats privats de Telegram no permeten fer còpies.
Com ja suposareu, tota conversa passa per un servidor que resol on s'envia el text. Es podria "capturar" el text, llegir-lo, i després enviar-lo com si res.
La porta del darrera és possible en els xats i xats de grup de Telegram. Impossible en el cas de xats privats de Telegram.
Pel que fa a WhatsApp, caldria que s'introduís una clau pública diferent i només serviria per a nous missatges. Els canvis de clau pública a WhatsApp són transparents, excepte que s'activi Settings -> Account -> Security -> Show Security Notifications
. Un cop activada aquesta opció, si hi hagués un canvi de clau, es notificaria amb un missatge. Aturaríem llavors la conversa, fins que la clau tornés a ser la mateixa.
Ho entenc. Aquí quatre indicacions per anar ràpid:
Feu servir WhatsApp. És més segur. Per evitar que en un futur es puguin veure les converses, esborreu i demaneu que esborrin el contingut del xat.
Feu servir el xat privat de Telegram i esborreu un cop acabat.
Recordeu que les converses normals queden al dispositiu. Si li agafen el dispositiu a un dels usuaris, l'altre o els altres quedaran al descobert. Esborreu els continguts.
No sé si us heu fixat, però no hi ha possibilitat de fer un xat de grup amb contingut altament sensible. Com a la vida real.