Can PKCS5Padding be in AES/GCM mode? - java

What's the padding mode for AES/GCM? I understood it can be NoPadding, as in ECB mode it can be PKCS5Padding, how about in GCM mode? in JCE interface, we need provide "algorithm/mode/padding" (Reference).
So I used the following code to get the instance and it works in JDK but failed in IBM SDK which says
cannot find provider for supporting AES/GCM/PKCS5Padding
Cipher.getInstance("AES/GCM/PKCS5Padding");
What's real use case for padding?

GCM is a streaming mode which means that the ciphertext is only as long as the plaintext (not including authentication tag). GCM doesn't require a padding. This means that the PKCS5Padding version is actually only a synonym for NoPadding for convenience during programming.
Some providers don't have this strange mode. Java has pluggable cryptographic providers and basically all JRE distributions have a default cryptographic provider which may have different cipher strings and defaults than those of other providers.
There are cases where padding the plaintext makes sense. For example, you can hide the length of the actual plaintext by appending a random length PKCS5Padding.

Related

Bouncy Castle Configuration for TLS

I am using a test app that used java for TLS communication. Standard Oracle java is installed in my system.
I need to use the TLS_DHE_RSA_WITH_AES_128_CCM cipher suite, which is not supported by standard Java, so many suggested using Bouncy Castle. I downloaded and copied the bcprov-ext-jdk18on-171.jar to $JAVA_HOME/lib folder.
Also, updated java.security file to include Bouncy Castle in the provider list as below:
security.provider.4=org.bouncycastle.jce.provider.BouncyCastleProvider
I still cannot get TLS_DHE_RSA_WITH_AES_128_CCM to work though.
Are the steps I did sufficient and correct? Can someone suggest the steps to install and configure Bouncy Castle?
The BouncyCastleProvider adds cryptographic algorithms such as the AES in the CCM mode of operation to the available algorithms of Cipher and other classes. As CCM is not included by default in Java, you will need to register this provider through code (i.e. Security.addProvider(new BouncyCastleProvider)) or adding it into the java.security file (as demonstrated in the question). You will probably want to add it to the end of the provider list as the algorithms of the Oracle provider are generally better tested and may be sped up using hardware acceleration.
However, the BouncyCastleProvider does not contain an implementation of the TLS protocol. You'd need to register the BouncyCastleJsseProvider for that instead. This is required as the Java TLS implementation won't magically know how to use the CCM implementation within Bouncy Castle. JSSE is an acronym of the Java Secure Socket Extension.
You can add that provider at the start of the providers so you know for sure that this provider is used for implementing TLS:
Security.insertProviderAt(new rg.bouncycastle.jsse.provider.BouncyCastleJsseProvider(), 1);
And you can also directly register it in the java.security file.
Note that the JSSE provider doesn't provide implementations such as RSA or AES for Cipher or Signature so it should not be in the way.

Would having a constant KeyStore make this any less secure?

I'm writing a bit of a net utility, and I want it to have three protocols. PLAIN_TEXT, which, obviously, sends plain text/bytes over the network. ENCRYPTED_UNSECURED, which uses encryption, but doesn't verify any identities, and ENCRYPTED_SECURED, which uses SSL or TSL.
Right now, I've implemented PLAIN_TEXT, and I've partially implemented ENCRYPTED_UNSECURED, but I've hit a block. I'm using SSLSockets for ENCRYPTED_UNSECURED, but with self-signed certs and a fake trust manager, however, the self-signed certs need to come from a key manager, which comes from a keyfile, generated by the java key tool.
What I want to know is: would using the same key file in every instance of the server/client subtract from the security of the encryption? As it is ENCRYPTED_UNSECURED, I don't care about the security of the authentication.
Note: this is being done in java.
EDIT: Why this is not a duplicate?
I'm not trying to import the certificate, I know how to do that, I want to know if using the same certificate could decrease the security of SSL/TSL's encryption protocol.
First, don't use actual SSL; SSLv2 was broken long ago (before 2000), and SSLv3 is now broken in most situations by POODLE (see Wikipedia and/or about a dozen questions on security.SE and crypto.SE). (Note the pseudoprotocol SSLv2Hello in Java/JSSE is not actually SSLv2 and is not a security vulnerability; OTOH since maybe 2010 it is very rarely needed or useful and nowadays more likely to cause confusion.)
Caveat: Java uses an "architecture" for cryptography that allows the same function(s) to be performed by different "providers" depending on how (by whom) your JRE is built and whether your installation has been modified. I will assume you use an Oracle (or formerly Sun) version of Java, or another version that uses the same cryptoproviders, which may include OpenJDK (which is mostly the same source as Oracle/Sun). In particular #Michal's answer seems to assume IBM although I see nothing in your question indicating this; IBM Java although otherwise compatible with Oracle/Sun Java has its own set of cryptoproviders and I don't know if any of the IBM differences affect the issues here.
Finally(!) to your question: distributing one privatekey (keystore) to numerous parties increases the risk of compromise at least proportionally to the number -- perhaps more because people are usually less careful about things that they perceive as someone else's responsibility.
TLS (like SSL before it) supports several different keyexchange options.
Ephemeral Diffie-Hellman in either classic (Zp) form DHE or elliptic-curve form ECDHE. These are usually preferred, and in particular Java/JSSE client orders them first (except for bugs on some early updates of Java7) because they provide Perfect Forward Secrecy; treating now as the beginning of the future -- as the saying goes 'today is the first day of the rest of your life' -- this also preserves confidentiality even if the server privatekey is already compromised, at least assuming the DHE/ECDHE implementation is correct.
Be sure not to use (Zp) DHE if the server runs on Java7 or earlier; those versions used 768-bit DH group which is too small. Java8 defaults to 1024, which is enough except perhaps against top adversaries like NSA, see details at http://weakdh.org; and can be configured for 2048 which is definitely enough, see
How to expand DH key size to 2048 in java 8
or several others. Note Java7 and up (but not 6 out of the box) support both DHE and ECDHE and prefer ECDHE, and Java ECDHE uses adequate curves, so in practice this should not be a problem.
(Plain) RSA. This is not secure if the privatekey is compromised, so in your situation you should if at all possible disable all plain-RSA ciphersuites. Ciphersuites of the form {TLS,SSL}_DHE_RSA_.. and TLS_ECDHE_RSA_... use RSA only for authentication not encryption; it is {SSL,TLS}_RSA_... that you must avoid.
Anonymous. TLS also supports keyexchange with DH or ECDH ephemeral keys but NO AUTHENTICATION (i.e. no certificate at all); these suites are called 'anonymous' instead of ephemeral and have the form {SSL/TLS}_{DH,ECDH}_anon_.... This is actually the exact technical match to your goal of providing confidentiality but not authentication, and needs NO keystore on the server or truststore on the client, plus avoids the hostname issue below. The possible downside is that anonymous suites are disabled by default, precisely because most users expect 'Secure Sockets' or 'Transport Security' to be secure, so you must enable them (at both ends); also if your organization (or your user's if different) has actually thought about a security policy, that thinking fairly often prohibits anonymous TLS for the same reason, and unlike some policy items this one can almost always be enforced by scans or monitors.
Others. TLS also supports nonephemeral aka static DH and ECDH, but practically no one uses them. TLS also supports non-PKC schemes using Kerberos, SRP, or just an arbitrary key (PSK), but these generally are appropriate only in special situations. Of these Java supports static-ECDH and Kerberos; using static-ECDH in your situation would be as insecure as plain-RSA, and IME even in environments where Kerberos is available using it with Java is about as much fun as hitting yourself in the head with hammers.
Hostname check: finally, for (non-anonymous) suites using a certificate, Java SSL/TLS client normally checks that the name used to connect to the server (either a domainname or an IP address) matches the certificate; the certificate must contain either
the name/address of the server, of which there can be more than one using SubjectAltNames aka SAN extension which is supported by keytool beginning in Java7 -- but a full list of names is difficult to arrange if you are going to use one cert on many servers especially ones you didn't identify in advance;
or a name with a 'wildcard' in the first component only: i.e. *.fred.example.com can be used for test1.fred.example.com test9999.fred.example.com anything.fred.example.com but NOT test.john.example.com anything.example.net or even fred.example.com (one level higher).
This check can be overridden, although the details vary some depending on whether you are using HTTPS or not and the Java version. Using anonymous suite(s) as above avoids the issue entirely.

AES 256 privacy with Adventnet Java API - traps not received

I am using Adventnet 4.0.0 API to receive traps. When AES 128 is used as privacy authentication it is successfully received, whereas when I change to use AES 256 it is not receiving. But Wireshark is able to receive and decode properly.
Any thing I am missing or Adventnet 4.0.0 is not capable of handling AES 256?
The WebNMS page for the Java SNMP API lists the supported encryption schemes:
SNMPv3 security: Support for HMAC-SHA-96, HMAC-MD5-96, CBC-DES, CBC-3DES, CFB-AES-128, CFB-AES-192, CFB-AES-256 bit encryption.
If you don't think it's working like it should, it's always worth shooting off an email to their support crew.
Hard to say more than that without seeing your code.

Encrypted RMI communication without using certificates

I need to make two java proceses on the same host to communicate securely. I do not need to authenticate the processes so I don't want to use certificates.
I want to generate a random key in the server and client, exchange the keys between the processes using Elgamal; establish common symmetric key across the processes; and then communicate securely.
As far as I can think of, this can be done by implementing RMIServerSocketFactory and RMIClientSocketFactory interfaces to establish symmetric key as discussed above.
Is there already an implementation to do that?
Or is there a way to configure SslRMIServerSocketFactory and SslRMIClientSocketFactory to start using ElGamal as the key exchange protocol
ElGamal is preferred choice over RSA as ElGamal will generate random symmetric keys for each handshake while RSA will generate static keys every time.
I need to make two java proceses on the same host to communicate
securely. I do not need to authenticate the processes so I don't want
to use certificates.
Your reasoning is flawed from the start unfortunately. However "hardened" a communication channel is, you'll always want to make sure you're communicating with the intended party if you want to exchange data secretly. Authentication in one form or another is necessary to do so.
In theory, you can do away with certificates and use PSK cipher suites (which would effectively include the authentication step). This isn't supported by default with the Oracle/OpenJDK JRE. In addition, if you're working on the assumption that your certificate's private key would be compromised (as suggested by your other question), the same problem could happen with the pre-shared keys anyway.

What mode to use to decrypt RSA message from iPhone in Java?

My friend has encrypted data with PKCS1 padding on an iPhone.
How can I decrypt that data in Java?
Java requires me to specify "algorithm/ciphermode/padding". The padding and the algorithm are known, but neither of us knows the cipher mode; it is not specified when encrypting on the iPhone.
using bouncy castle and this code should be simple
RSA doesn't really use a "mode"; modes are for block ciphers.
The built-in Sun provider will accept "RSA/ECB/PKCS1Padding" as a Cipher name. ECB is "Electronic Code Book", which doesn't mix any information from "block" to block; it is sort of "no cipher mode."
Other providers accept "None" as a cipher mode with RSA.
BouncyCastle is a good provider. I'm not sure why you would need to take the trouble to install it in this case, however. The SunJCE provider will work fine.

Categories