diff --git a/Cargo.toml b/Cargo.toml
index 490c46d..9981489 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,7 +17,7 @@ maintenance = { status = "passively-maintained" }
 
 [dependencies]
 byteorder = "1.1"
-crypto_box = { version = "0.7.1", features = ["serde"] }
+crypto_box = { version = "0.9.1", features = ["serde"] }
 data-encoding = "2.1"
 failure = "0.1"
 futures = "0.1.0"  # Make sure to use same version as websocket
@@ -31,7 +31,7 @@ serde = { version = "1", features = ["derive"] }
 tokio-core = "0.1"
 tokio-timer = "0.1"
 websocket = { version = "0.26", default-features = false, features = ["async", "async-ssl"] }
-xsalsa20poly1305 = "0.8"
+xsalsa20poly1305 = "0.9"
 
 [dev-dependencies]
 anyhow = "1"
diff --git a/src/crypto_types.rs b/src/crypto_types.rs
index 9c620e2..7372bae 100644
--- a/src/crypto_types.rs
+++ b/src/crypto_types.rs
@@ -8,8 +8,8 @@ use std::io::Write;
 use std::{cmp, convert::TryInto, fmt};
 
 use crypto_box::{
-    aead::{generic_array::GenericArray, Aead, NewAead},
-    rand_core::OsRng,
+    aead::{generic_array::GenericArray, Aead, KeyInit, OsRng},
+    SalsaBox,
 };
 use data_encoding::{HEXLOWER, HEXLOWER_PERMISSIVE};
 use serde::{
@@ -141,7 +141,7 @@ impl KeyPair {
     /// Warning: Be careful with this! The only reason to access the private
     /// key is probably to be able to restore it when working with trusted keys.
     pub fn private_key_hex(&self) -> String {
-        HEXLOWER.encode(self.private_key.as_bytes())
+        HEXLOWER.encode(&self.private_key.to_bytes())
     }
 
     /// Encrypt data for the specified public key with the private key.
@@ -151,7 +151,7 @@ impl KeyPair {
         nonce: Nonce,
         other_key: &PublicKey,
     ) -> SignalingResult<Vec<u8>> {
-        let cbox = crypto_box::Box::new(other_key, &self.private_key);
+        let cbox = SalsaBox::new(other_key, &self.private_key);
         cbox.encrypt(&nonce.into(), data)
             .map_err(|_| SignalingError::Crypto("Could not encrypt data".to_string()))
     }
@@ -167,7 +167,7 @@ impl KeyPair {
         nonce: Nonce,
         other_key: &PublicKey,
     ) -> SignalingResult<Vec<u8>> {
-        let cbox = crypto_box::Box::new(other_key, &self.private_key);
+        let cbox = SalsaBox::new(other_key, &self.private_key);
         cbox.decrypt(&nonce.into(), data)
             .map_err(|_| SignalingError::Crypto("Could not decrypt data".to_string()))
     }
@@ -287,7 +287,7 @@ impl UnsignedKeys {
         (&mut bytes[32..64])
             .write_all(self.client_public_permanent_key.as_bytes())
             .unwrap();
-        let cbox = crypto_box::Box::new(
+        let cbox = SalsaBox::new(
             client_public_permanent_key,
             server_session_keypair.private_key(),
         );
@@ -315,7 +315,7 @@ impl SignedKeys {
         nonce: Nonce,
     ) -> SignalingResult<UnsignedKeys> {
         // Decrypt bytes
-        let cbox = crypto_box::Box::new(server_public_permanent_key, permanent_key.private_key());
+        let cbox = SalsaBox::new(server_public_permanent_key, permanent_key.private_key());
         let decrypted = cbox
             .decrypt(&nonce.into(), &self.0[..])
             .map_err(|_| SignalingError::Crypto("Could not decrypt signed keys".to_string()))?;
@@ -413,7 +413,7 @@ use crate::test_helpers::TestRandom;
 #[cfg(test)]
 impl TestRandom for PublicKey {
     fn random() -> PublicKey {
-        let mut rng = crypto_box::rand_core::OsRng;
+        let mut rng = crypto_box::aead::OsRng;
         let private_key = PrivateKey::generate(&mut rng);
         private_key.public_key()
     }
@@ -431,7 +431,7 @@ mod tests {
             let ks1 = KeyPair::new();
             let ks2 = KeyPair::new();
             assert_ne!(ks1.public_key(), ks2.public_key());
-            assert_ne!(ks1.private_key().as_bytes(), ks2.private_key().as_bytes());
+            assert_ne!(ks1.private_key().to_bytes(), ks2.private_key().to_bytes());
         }
     }
 
@@ -633,7 +633,7 @@ mod tests {
             .sign(&kp_server, kp_client.public_key(), unsafe { nonce.clone() });
 
         // Decrypt directly
-        let cbox = crypto_box::Box::new(kp_server.public_key(), kp_client.private_key());
+        let cbox = SalsaBox::new(kp_server.public_key(), kp_client.private_key());
         let decrypted = cbox
             .decrypt(&unsafe { nonce.clone() }.into(), &signed.0[..])
             .unwrap();
diff --git a/src/protocol/cookie.rs b/src/protocol/cookie.rs
index f00942b..82d4f33 100644
--- a/src/protocol/cookie.rs
+++ b/src/protocol/cookie.rs
@@ -2,7 +2,7 @@
 
 use std::fmt;
 
-use crypto_box::rand_core::{OsRng, RngCore};
+use crypto_box::aead::{OsRng, rand_core::RngCore};
 use serde::{
     de::{Deserialize, Deserializer, Error as SerdeError, Visitor},
     ser::{Serialize, Serializer},
diff --git a/src/protocol/csn.rs b/src/protocol/csn.rs
index 5924ad6..39a73c0 100644
--- a/src/protocol/csn.rs
+++ b/src/protocol/csn.rs
@@ -6,7 +6,7 @@
 
 use std::cmp;
 
-use crypto_box::rand_core::{OsRng, RngCore};
+use crypto_box::aead::{OsRng, rand_core::RngCore};
 
 use crate::errors::{SignalingError, SignalingResult};
 
diff --git a/src/protocol/messages.rs b/src/protocol/messages.rs
index 4ce8ffc..ab00443 100644
--- a/src/protocol/messages.rs
+++ b/src/protocol/messages.rs
@@ -140,7 +140,7 @@ impl ClientHello {
     /// Create a new instance with dummy data. Used in testing.
     #[cfg(test)]
     pub(crate) fn random() -> Self {
-        use crypto_box::rand_core::{OsRng, RngCore};
+        use crypto_box::aead::{OsRng, rand_core::RngCore};
         let mut bytes = [0u8; 32];
         OsRng.fill_bytes(&mut bytes);
         Self {
@@ -164,7 +164,7 @@ impl ServerHello {
     /// Create a new instance with dummy data. Used in testing.
     #[cfg(test)]
     pub(crate) fn random() -> Self {
-        use crypto_box::rand_core::{OsRng, RngCore};
+        use crypto_box::aead::{OsRng, rand_core::RngCore};
         let mut bytes = [0u8; 32];
         OsRng.fill_bytes(&mut bytes);
         Self {
@@ -304,7 +304,7 @@ impl Token {
     /// Create a new instance with dummy data. Used in testing.
     #[cfg(test)]
     pub(crate) fn random() -> Self {
-        use crypto_box::rand_core::{OsRng, RngCore};
+        use crypto_box::aead::{OsRng, rand_core::RngCore};
         let mut bytes = [0u8; 32];
         OsRng.fill_bytes(&mut bytes);
         Self {
@@ -325,7 +325,7 @@ impl Key {
     /// Create a new instance with dummy data. Used in testing.
     #[cfg(test)]
     pub(crate) fn random() -> Self {
-        use crypto_box::rand_core::{OsRng, RngCore};
+        use crypto_box::aead::{OsRng, rand_core::RngCore};
         let mut bytes = [0u8; 32];
         OsRng.fill_bytes(&mut bytes);
         Self {
diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs
index ffa9a17..0165c6e 100644
--- a/src/protocol/mod.rs
+++ b/src/protocol/mod.rs
@@ -15,9 +15,12 @@ use std::{
     time::Duration,
 };
 
-use crypto_box::aead::{
-    generic_array::{typenum::U24, GenericArray},
-    Aead,
+use crypto_box::{
+    aead::{
+        generic_array::{typenum::U24, GenericArray},
+        Aead,
+    },
+    SalsaBox,
 };
 use rmpv::Value;
 
@@ -924,7 +927,7 @@ pub(crate) trait Signaling {
 
     // Raw encryption / decryption
 
-    fn get_crypto_box(&self) -> SignalingResult<crypto_box::Box> {
+    fn get_crypto_box(&self) -> SignalingResult<SalsaBox> {
         let peer = self.get_peer().ok_or_else(|| SignalingError::NoPeer)?;
         let peer_session_public_key = peer
             .session_key()
@@ -933,7 +936,7 @@ pub(crate) trait Signaling {
             .keypair()
             .map(|keypair: &KeyPair| keypair.private_key())
             .ok_or_else(|| SignalingError::Crash("Our session private key not set".into()))?;
-        Ok(crypto_box::Box::new(
+        Ok(SalsaBox::new(
             peer_session_public_key,
             our_session_private_key,
         ))
diff --git a/src/protocol/tests/mod.rs b/src/protocol/tests/mod.rs
index 0574e64..99051f9 100644
--- a/src/protocol/tests/mod.rs
+++ b/src/protocol/tests/mod.rs
@@ -1,5 +1,6 @@
 //! Protocol tests.
-use crypto_box::{generate_nonce, rand_core::OsRng};
+use crypto_box::{aead::OsRng, SalsaBox};
+use xsalsa20poly1305::XSalsa20Poly1305;
 
 use crate::{
     crypto::PrivateKey,
@@ -176,7 +177,7 @@ fn test_encrypt_decrypt_raw_with_session_keys_no_peer() {
         None,
         None,
     );
-    let nonce = generate_nonce(&mut OsRng);
+    let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng);
     assert_eq!(
         signaling.encrypt_raw_with_session_keys(&[1, 2, 3], &nonce),
         Err(SignalingError::NoPeer)
@@ -194,7 +195,7 @@ fn test_encrypt_raw_with_session_keys_with_peer() {
     let peer_kp = KeyPair::new();
     let our_kp = KeyPair::new();
     let our_private_key_clone = our_kp.private_key().clone();
-    let nonce = generate_nonce(&mut OsRng);
+    let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng);
 
     // Create signaling instance
     let mut signaling = MockSignaling::new(
@@ -215,7 +216,7 @@ fn test_encrypt_raw_with_session_keys_with_peer() {
     assert_ne!(&data, ciphertext.as_slice());
 
     // Verify
-    let cbox = crypto_box::Box::new(peer_kp.public_key(), &our_private_key_clone);
+    let cbox = SalsaBox::new(peer_kp.public_key(), &our_private_key_clone);
     assert_eq!(cbox.decrypt(&nonce, &*ciphertext), Ok(vec![2, 3, 4, 5]));
 }
 
@@ -266,12 +267,12 @@ fn test_decrypt_raw_with_session_keys_with_peer() {
     // Generate keypairs and nonce
     let peer_kp = KeyPair::new();
     let our_kp = KeyPair::new();
-    let nonce = generate_nonce(&mut OsRng);
+    let nonce = XSalsa20Poly1305::generate_nonce(&mut OsRng);
 
     // Encrypt data
     let data = [1, 2, 3, 4];
 
-    let cbox = crypto_box::Box::new(peer_kp.public_key(), our_kp.private_key());
+    let cbox = SalsaBox::new(peer_kp.public_key(), our_kp.private_key());
     let ciphertext = cbox.encrypt(&nonce, &data[..]).unwrap();
 
     // Create signaling instance
@@ -287,7 +288,10 @@ fn test_decrypt_raw_with_session_keys_with_peer() {
 
     // Decrypt with wrong nonce
     assert_eq!(
-        signaling.decrypt_raw_with_session_keys(&ciphertext, &generate_nonce(&mut OsRng)),
+        signaling.decrypt_raw_with_session_keys(
+            &ciphertext,
+            &XSalsa20Poly1305::generate_nonce(&mut OsRng)
+        ),
         Err(SignalingError::Crypto("Could not decrypt bytes".into()))
     );