예제 #1
0
 public static byte[] ArgonHashBinary(byte[] password, byte[] salt, long opsLimit, int memLimit, long outputLength = 16L)
 {
     if (password == null)
     {
         throw new ArgumentNullException("password", "Password cannot be null");
     }
     if (salt == null)
     {
         throw new ArgumentNullException("salt", "Salt cannot be null");
     }
     if ((long)salt.Length != 16L)
     {
         throw new SaltOutOfRangeException(string.Format("Salt must be {0} bytes in length.", 16u));
     }
     if (opsLimit < 3L)
     {
         throw new ArgumentOutOfRangeException("opsLimit", "opsLimit the number of passes, has to be at least 3");
     }
     if (memLimit <= 0)
     {
         throw new ArgumentOutOfRangeException("memLimit", "memLimit cannot be zero or negative");
     }
     if (outputLength <= 0L)
     {
         throw new ArgumentOutOfRangeException("outputLength", "OutputLength cannot be zero or negative");
     }
     byte[] array = new byte[outputLength];
     if (SodiumLibrary.crypto_pwhash(array, (long)array.Length, password, (long)password.Length, salt, opsLimit, memLimit, 1) != 0)
     {
         throw new OutOfMemoryException("Internal error, hash failed (usually because the operating system refused to allocate the amount of requested memory).");
     }
     return(array);
 }
예제 #2
0
 public static KeyPair GenerateKeyPair()
 {
     byte[] publicKey = new byte[32];
     byte[] array     = new byte[64];
     SodiumLibrary.crypto_sign_keypair(publicKey, array);
     return(new KeyPair(publicKey, array));
 }
예제 #3
0
        public static byte[] Hash(byte[] message, byte[] key, int bytes)
        {
            int keyLength;

            if (key != null)
            {
                if (key.Length > 64 || key.Length < 16)
                {
                    throw new KeyOutOfRangeException(string.Format("key must be between {0} and {1} bytes in length.", 16, 64));
                }
                keyLength = key.Length;
            }
            else
            {
                key       = new byte[0];
                keyLength = 0;
            }
            if (bytes > 64 || bytes < 16)
            {
                throw new BytesOutOfRangeException("bytes", bytes, string.Format("bytes must be between {0} and {1} bytes in length.", 16, 64));
            }
            byte[] array = new byte[bytes];
            SodiumLibrary.crypto_generichash(array, array.Length, message, (long)message.Length, key, keyLength);
            return(array);
        }
예제 #4
0
 public static byte[] OpenDetached(byte[] cipherText, byte[] mac, byte[] nonce, byte[] secretKey, byte[] publicKey)
 {
     if (secretKey == null || secretKey.Length != 32)
     {
         throw new KeyOutOfRangeException("secretKey", (secretKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (publicKey == null || publicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("publicKey", (publicKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (mac == null || mac.Length != 16)
     {
         throw new MacOutOfRangeException("mac", (mac == null) ? 0 : mac.Length, string.Format("mac must be {0} bytes in length.", 16));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[cipherText.Length];
     if (SodiumLibrary.crypto_box_open_detached(array, cipherText, mac, (long)cipherText.Length, nonce, secretKey, publicKey) != 0)
     {
         throw new CryptographicException("Failed to open public detached Box");
     }
     return(array);
 }
예제 #5
0
 internal static void Init()
 {
     if (!SodiumCore._isInit)
     {
         SodiumLibrary.init();
         SodiumCore._isInit = true;
     }
 }
예제 #6
0
 public static byte[] Base(byte[] secretKey)
 {
     if (secretKey == null || secretKey.Length != 32)
     {
         throw new KeyOutOfRangeException("secretKey", (secretKey == null) ? 0 : secretKey.Length, string.Format("secretKey must be {0} bytes in length.", 32));
     }
     byte[] array = new byte[32];
     SodiumLibrary.crypto_scalarmult_base(array, secretKey);
     return(array);
 }
예제 #7
0
 public static byte[] Hash(byte[] message, byte[] key)
 {
     if (key == null || key.Length != 16)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 16));
     }
     byte[] array = new byte[8];
     SodiumLibrary.crypto_shorthash(array, message, (long)message.Length, key);
     return(array);
 }
예제 #8
0
 public static byte[] SignHmacSha512(byte[] message, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     byte[] array = new byte[64];
     SodiumLibrary.crypto_auth_hmacsha512(array, message, (long)message.Length, key);
     return(array);
 }
예제 #9
0
        public static string BinaryToHex(byte[] data)
        {
            byte[] array   = new byte[data.Length * 2 + 1];
            IntPtr expr_1F = SodiumLibrary.sodium_bin2hex(array, array.Length, data, data.Length);

            if (expr_1F == IntPtr.Zero)
            {
                throw new OverflowException("Internal error, encoding failed.");
            }
            return(Marshal.PtrToStringAnsi(expr_1F));
        }
예제 #10
0
 public static KeyPair GenerateKeyPair(byte[] seed)
 {
     byte[] publicKey = new byte[32];
     byte[] array     = new byte[64];
     if (seed == null || seed.Length != 32)
     {
         throw new SeedOutOfRangeException("seed", (seed == null) ? 0 : seed.Length, string.Format("seed must be {0} bytes in length.", 32));
     }
     SodiumLibrary.crypto_sign_seed_keypair(publicKey, array, seed);
     return(new KeyPair(publicKey, array));
 }
예제 #11
0
 public static bool VerifyHmacSha256(byte[] message, byte[] signature, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (signature == null || signature.Length != 32)
     {
         throw new SignatureOutOfRangeException("signature", (signature == null) ? 0 : signature.Length, string.Format("signature must be {0} bytes in length.", 32));
     }
     return(SodiumLibrary.crypto_auth_hmacsha256_verify(signature, message, (long)message.Length, key) == 0);
 }
예제 #12
0
 public static bool ScryptHashStringVerify(byte[] hash, byte[] password)
 {
     if (password == null)
     {
         throw new ArgumentNullException("password", "Password cannot be null");
     }
     if (hash == null)
     {
         throw new ArgumentNullException("hash", "Hash cannot be null");
     }
     return(SodiumLibrary.crypto_pwhash_scryptsalsa208sha256_str_verify(hash, password, (long)password.Length) == 0);
 }
예제 #13
0
        public static byte[] SignDetached(byte[] message, byte[] key)
        {
            if (key == null || key.Length != 64)
            {
                throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 64));
            }
            byte[] array = new byte[64];
            long   num   = 0L;

            SodiumLibrary.crypto_sign_detached(array, ref num, message, (long)message.Length, key);
            return(array);
        }
예제 #14
0
 public static byte[] Create(byte[] message, byte[] recipientPublicKey)
 {
     if (recipientPublicKey == null || recipientPublicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("recipientPublicKey", (recipientPublicKey == null) ? 0 : recipientPublicKey.Length, string.Format("recipientPublicKey must be {0} bytes in length.", 32));
     }
     byte[] array = new byte[message.Length + 48];
     if (SodiumLibrary.crypto_box_seal(array, message, (long)message.Length, recipientPublicKey) != 0)
     {
         throw new CryptographicException("Failed to create SealedBox");
     }
     return(array);
 }
예제 #15
0
 public static byte[] ConvertEd25519PublicKeyToCurve25519PublicKey(byte[] ed25519PublicKey)
 {
     if (ed25519PublicKey == null || ed25519PublicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("ed25519PublicKey", (ed25519PublicKey == null) ? 0 : ed25519PublicKey.Length, string.Format("ed25519PublicKey must be {0} bytes in length.", 32));
     }
     byte[] array = new byte[32];
     if (SodiumLibrary.crypto_sign_ed25519_pk_to_curve25519(array, ed25519PublicKey) != 0)
     {
         throw new CryptographicException("Failed to convert public key.");
     }
     return(array);
 }
예제 #16
0
 public static byte[] ConvertEd25519SecretKeyToCurve25519SecretKey(byte[] ed25519SecretKey)
 {
     if (ed25519SecretKey == null || (ed25519SecretKey.Length != 32 && ed25519SecretKey.Length != 64))
     {
         throw new KeyOutOfRangeException("ed25519SecretKey", (ed25519SecretKey == null) ? 0 : ed25519SecretKey.Length, string.Format("ed25519SecretKey must be either {0} or {1} bytes in length.", 32, 64));
     }
     byte[] array = new byte[32];
     if (SodiumLibrary.crypto_sign_ed25519_sk_to_curve25519(array, ed25519SecretKey) != 0)
     {
         throw new CryptographicException("Failed to convert secret key.");
     }
     return(array);
 }
예제 #17
0
 public static byte[] ExtractEd25519PublicKeyFromEd25519SecretKey(byte[] ed25519SecretKey)
 {
     if (ed25519SecretKey == null || ed25519SecretKey.Length != 64)
     {
         throw new KeyOutOfRangeException("ed25519SecretKey", (ed25519SecretKey == null) ? 0 : ed25519SecretKey.Length, string.Format("ed25519SecretKey must be {0} bytes in length.", 64));
     }
     byte[] array = new byte[32];
     if (SodiumLibrary.crypto_sign_ed25519_sk_to_pk(array, ed25519SecretKey) != 0)
     {
         throw new CryptographicException("Failed to extract public key from secret key.");
     }
     return(array);
 }
예제 #18
0
        public static byte[] Sign(byte[] message, byte[] key)
        {
            if (key == null || key.Length != 64)
            {
                throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 64));
            }
            byte[] array = new byte[message.Length + 64];
            long   num   = 0L;

            SodiumLibrary.crypto_sign(array, ref num, message, (long)message.Length, key);
            byte[] array2 = new byte[num];
            Array.Copy(array, 0L, array2, 0L, num);
            return(array2);
        }
예제 #19
0
        public static byte[] Verify(byte[] signedMessage, byte[] key)
        {
            if (key == null || key.Length != 32)
            {
                throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
            }
            byte[] array = new byte[signedMessage.Length];
            long   num   = 0L;

            if (SodiumLibrary.crypto_sign_open(array, ref num, signedMessage, (long)signedMessage.Length, key) != 0)
            {
                throw new CryptographicException("Failed to verify signature.");
            }
            byte[] array2 = new byte[num];
            Array.Copy(array, 0L, array2, 0L, num);
            return(array2);
        }
예제 #20
0
 public static byte[] Open(byte[] cipherText, byte[] recipientSecretKey, byte[] recipientPublicKey)
 {
     if (recipientSecretKey == null || recipientSecretKey.Length != 32)
     {
         throw new KeyOutOfRangeException("recipientPublicKey", (recipientSecretKey == null) ? 0 : recipientSecretKey.Length, string.Format("recipientSecretKey must be {0} bytes in length.", 32));
     }
     if (recipientPublicKey == null || recipientPublicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("recipientPublicKey", (recipientPublicKey == null) ? 0 : recipientPublicKey.Length, string.Format("recipientPublicKey must be {0} bytes in length.", 32));
     }
     byte[] array = new byte[cipherText.Length - 48];
     if (SodiumLibrary.crypto_box_seal_open(array, cipherText, (long)cipherText.Length, recipientPublicKey, recipientSecretKey) != 0)
     {
         throw new CryptographicException("Failed to open SealedBox");
     }
     return(array);
 }
예제 #21
0
 public static byte[] Decrypt(byte[] cipherText, byte[] nonce, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[cipherText.Length];
     if (SodiumLibrary.crypto_stream_xor(array, cipherText, (long)cipherText.Length, nonce, key) != 0)
     {
         throw new CryptographicException("Error derypting message.");
     }
     return(array);
 }
예제 #22
0
 public static byte[] EncryptChaCha20(byte[] message, byte[] nonce, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 8)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 8));
     }
     byte[] array = new byte[message.Length];
     if (SodiumLibrary.crypto_stream_chacha20_xor(array, message, (long)message.Length, nonce, key) != 0)
     {
         throw new CryptographicException("Error encrypting message.");
     }
     return(array);
 }
예제 #23
0
 public static DetachedBox CreateDetached(byte[] message, byte[] nonce, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[message.Length];
     byte[] mac   = new byte[16];
     if (SodiumLibrary.crypto_secretbox_detached(array, mac, message, (long)message.Length, nonce, key) != 0)
     {
         throw new CryptographicException("Failed to create detached SecretBox");
     }
     return(new DetachedBox(array, mac));
 }
예제 #24
0
 public static byte[] Open(byte[] cipherText, byte[] nonce, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[cipherText.Length];
     if (SodiumLibrary.crypto_secretbox_open(array, cipherText, (long)cipherText.Length, nonce, key) != 0)
     {
         throw new CryptographicException("Failed to open SecretBox");
     }
     byte[] array2 = new byte[array.Length - 32];
     Array.Copy(array, 32, array2, 0, array.Length - 32);
     return(array2);
 }
예제 #25
0
 public static byte[] Create(byte[] message, byte[] nonce, byte[] key)
 {
     if (key == null || key.Length != 32)
     {
         throw new KeyOutOfRangeException("key", (key == null) ? 0 : key.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[message.Length + 32];
     Array.Copy(message, 0, array, 32, message.Length);
     byte[] array2 = new byte[array.Length];
     if (SodiumLibrary.crypto_secretbox(array2, array, (long)array.Length, nonce, key) != 0)
     {
         throw new CryptographicException("Failed to create SecretBox");
     }
     return(array2);
 }
예제 #26
0
        public static byte[] HexToBinary(string hex)
        {
            byte[] array  = new byte[hex.Length >> 1];
            IntPtr intPtr = Marshal.AllocHGlobal(array.Length);
            int    num;
            bool   arg_43_0 = SodiumLibrary.sodium_hex2bin(intPtr, array.Length, hex, hex.Length, ":- ", out num, null) != 0;

            Marshal.Copy(intPtr, array, 0, num);
            Marshal.FreeHGlobal(intPtr);
            if (arg_43_0)
            {
                throw new Exception("Internal error, decoding failed.");
            }
            if (array.Length != num)
            {
                byte[] array2 = new byte[num];
                Array.Copy(array, 0, array2, 0, num);
                return(array2);
            }
            return(array);
        }
예제 #27
0
 public static byte[] Create(byte[] message, byte[] nonce, byte[] secretKey, byte[] publicKey)
 {
     if (secretKey == null || secretKey.Length != 32)
     {
         throw new KeyOutOfRangeException("secretKey", (secretKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (publicKey == null || publicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("publicKey", (publicKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     byte[] array = new byte[message.Length + 16];
     if (SodiumLibrary.crypto_box_easy(array, message, (long)message.Length, nonce, publicKey, secretKey) != 0)
     {
         throw new CryptographicException("Failed to create PublicKeyBox");
     }
     return(array);
 }
예제 #28
0
 public static byte[] Open(byte[] cipherText, byte[] nonce, byte[] secretKey, byte[] publicKey)
 {
     if (secretKey == null || secretKey.Length != 32)
     {
         throw new KeyOutOfRangeException("secretKey", (secretKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (publicKey == null || publicKey.Length != 32)
     {
         throw new KeyOutOfRangeException("publicKey", (publicKey == null) ? 0 : secretKey.Length, string.Format("key must be {0} bytes in length.", 32));
     }
     if (nonce == null || nonce.Length != 24)
     {
         throw new NonceOutOfRangeException("nonce", (nonce == null) ? 0 : nonce.Length, string.Format("nonce must be {0} bytes in length.", 24));
     }
     if (cipherText[0] == 0)
     {
         bool flag = true;
         for (int i = 0; i < 15; i++)
         {
             if (cipherText[i] != 0)
             {
                 flag = false;
                 break;
             }
         }
         if (flag)
         {
             byte[] array = new byte[cipherText.Length - 16];
             Array.Copy(cipherText, 16, array, 0, cipherText.Length - 16);
             cipherText = array;
         }
     }
     byte[] array2 = new byte[cipherText.Length - 16];
     if (SodiumLibrary.crypto_box_open_easy(array2, cipherText, (long)cipherText.Length, nonce, publicKey, secretKey) != 0)
     {
         throw new CryptographicException("Failed to open PublicKeyBox");
     }
     return(array2);
 }
예제 #29
0
 public static string ScryptHashString(string password, long opsLimit, int memLimit)
 {
     if (password == null)
     {
         throw new ArgumentNullException("password", "Password cannot be null");
     }
     if (opsLimit <= 0L)
     {
         throw new ArgumentOutOfRangeException("opsLimit", "opsLimit cannot be zero or negative");
     }
     if (memLimit <= 0)
     {
         throw new ArgumentOutOfRangeException("memLimit", "memLimit cannot be zero or negative");
     }
     byte[] array = new byte[102];
     byte[] bytes = Encoding.UTF8.GetBytes(password);
     if (SodiumLibrary.crypto_pwhash_scryptsalsa208sha256_str(array, bytes, (long)bytes.Length, opsLimit, memLimit) != 0)
     {
         throw new OutOfMemoryException("Internal error, hash failed (usually because the operating system refused to allocate the amount of requested memory).");
     }
     return(Encoding.UTF8.GetString(array));
 }
예제 #30
0
 public static byte[] HashSaltPersonal(byte[] message, byte[] key, byte[] salt, byte[] personal, int bytes = 64)
 {
     if (message == null)
     {
         throw new ArgumentNullException("message", "Message cannot be null");
     }
     if (salt == null)
     {
         throw new ArgumentNullException("salt", "Salt cannot be null");
     }
     if (personal == null)
     {
         throw new ArgumentNullException("personal", "Personal string cannot be null");
     }
     if (key != null && (key.Length > 64 || key.Length < 16))
     {
         throw new KeyOutOfRangeException(string.Format("key must be between {0} and {1} bytes in length.", 16, 64));
     }
     if (key == null)
     {
         key = new byte[0];
     }
     if (salt.Length != 16)
     {
         throw new SaltOutOfRangeException(string.Format("Salt must be {0} bytes in length.", 16));
     }
     if (personal.Length != 16)
     {
         throw new PersonalOutOfRangeException(string.Format("Personal bytes must be {0} bytes in length.", 16));
     }
     if (bytes > 64 || bytes < 16)
     {
         throw new BytesOutOfRangeException("bytes", bytes, string.Format("bytes must be between {0} and {1} bytes in length.", 16, 64));
     }
     byte[] array = new byte[bytes];
     SodiumLibrary.crypto_generichash_blake2b_salt_personal(array, array.Length, message, (long)message.Length, key, key.Length, salt, personal);
     return(array);
 }