# Oracle Native Network Encryption

As I come across environments where SQL\*Net is not encrypted I sometimes also notice that there are two common misconceptions about it:

* First, some are afraid that certificates *must* be involved and consequently maintaining a PKI infrastructure is deemed too complicated.
* Second, some are afraid of licensing issues, especially in respect to Standard Edition

Let me show you how none of those are true (certs certainly _can_ be involved, but they're not necessary for simple setups).

## License Requirements

To quote [Database Licensing Information User Manual, Release 23](https://docs.oracle.com/en/database/oracle/oracle-database/23/dblic/Licensing-Information.html#GUID-0F9EB85D-4610-4EDF-89C2-4916A0E7AC87):

_Note: Network encryption (native network encryption, network data integrity, and SSL/TLS) and strong authentication services (Kerberos, PKI, and RADIUS) are_ ***no longer*** _part of Oracle Advanced Security and are available in all licensed editions of all supported releases of Oracle Database._

I've also checked the same document for versions 19c and 12.1 and they both say the same thing.

Quick disclaimer: this blog simply reflects my understanding of Oracle's licensing documentation, so keep in mind that it is Oracle License Management Services (LMS) that always has the final authority regarding licensing matters.

That being said, it is also certainly a good idea to double check licensing restrictions when you hear about encryption or compression in regard to Standard Edition.

## Server Configuration

So, let's setup *Native Network Encryption* as this is the simplest way of enabling encryption over SQL\*Net. This method does not require any certificates and, in most cases, no client configuration. To enable it, we simply need to modify our `sqlnet.ora` file on the server. Like this:

```
SQLNET.ENCRYPTION_SERVER = REQUESTED
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUESTED
```

Or maybe like this if we want to be really strict about it:

```plaintext
SQLNET.ENCRYPTION_SERVER = REQUIRED             # default=ACCEPTED
SQLNET.ENCRYPTION_TYPES_SERVER = (AES256)       # default=all available algorithms
SQLNET.CRYPTO_CHECKSUM_SERVER = REQUIRED        # default=ACCEPTED
SQLNET.CRYPTO_CHECKSUM_TYPES_SERVER = (SHA512)  # default=all available algorithms
SQLNET.ALLOW_WEAK_CRYPTO_CLIENTS = FALSE        # default=TRUE
```

Defaults for `SQLNET.ENCRYPTION_SERVER` and `SQLNET.CRYPTO_CHECKSUM_SERVER` is `ACCEPTED`. Which would mean that if a client `REQUEST`s or `REQUIRE`s encryption then the server will be happy to encrypt the traffic. In our example though, as recommended for maximum security in official documentation, we only allow to establish encrypted connections, thus we specified `REQUIRED`. This is also why client configuration is not required in most cases: client also has default value for those parameters as `ACCEPTED`.

`SQLNET.ALLOW_WEAK_CRYPTO_CLIENTS` is more of a backward compatibility setting. If you need to support older clients then you may probably need to keep it on default value (`TRUE`).

Regarding algorithms, there is not much choice really. On 19c, there is `AES` for encryption and `SHA` for checksum. You can only require specific key lengths (e.g `AES256`) and hash sizes (e.g. `SHA512`). Well, to be exact, there are other algorithms (RC4, 3DES) supported, but they're also deprecated.

That's really, in essence, all there is to it.

## Client Configuration

Same settings can be used on client, just replace `_SERVER` with `_CLIENT`. So, if you're only in control of the client, you can still have connection encrypted, even if your DBA did not touch the `sqlnet.ora` file. Simply set `SQLNET.ENCRYPTION_CLIENT` and `SQLNET.CRYPTO_CHECKSUM_CLIENT` to either `REQUESTED` or `REQUIRED`.

## Is it Working?

Hackers will of course want to use tcpdump/Wireshark or similar to make it sure, but most of those people probably aren't reading this blog post as they already have some kind of encryption in place. For DBAs who trust performance views, you can simply do a following query:

```plaintext
SELECT network_service_banner
    FROM v$session_connect_info
    WHERE sid=sys_context('userenv','sid');
```

If enabled, you'll see (among other rows) those two:

```
NETWORK_SERVICE_BANNER
------------------------------------------------------------------------------------------
...
AES256 Encryption service adapter for Linux: Version 19.0.1.0.0 - Production
SHA1 Crypto-checksumming service adapter for Linux: Version 19.0.1.0.0 - Production
...
```

## What About Certificates?

... What you seek is called [Transport Layer Security (TLS)](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-secure-sockets-layer-authentication.html#GUID-6AD89576-526F-4D6B-A539-ADF4B840819F) and it can be configured so that either only server has a certificate or both (client+server). You can also **authenticate** clients (and servers) this way.

As I prefer to keep my blog posts concise and on-topic, I'll only provide a link to the documentation instead of discussing TLS in this post.

## References

* [Configuring Oracle Database Native Network Encryption and Data Integrity](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-network-data-encryption-and-integrity.html)
* [Transport Layer Security (TLS)](https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/configuring-secure-sockets-layer-authentication.html#GUID-6AD89576-526F-4D6B-A539-ADF4B840819F)
* [Database Licensing Information User Manual, Release 23](https://docs.oracle.com/en/database/oracle/oracle-database/23/dblic/Licensing-Information.html#GUID-0F9EB85D-4610-4EDF-89C2-4916A0E7AC87)


