Cryptographic features that enable SSH logins

Source: Internet
Author: User
Tags decrypt with public key hmac asymmetric encryption

I believe many people use SSH remote connection to Linux, then for our user name and password, SSH is how to encrypt and decrypt it? After the discussion with colleagues, and gradually understand the principle of encryption, the following one by one elaborated:

Encryption principle

SSH is the first through the asymmetric encryption to tell the server a symmetric encryption password, and then to verify the user name and password, using the encrypted password that both parties already know to encrypt and decrypt, see:
Explanation: Why is it useful to use asymmetric encryption and symmetric encryption in SSH? How safe is it? Since symmetric encryption was used later, why use asymmetric encryption at the beginning? Conversely, since asymmetric encryption is used, why is symmetric encryption used again?

    1. Asymmetric encryption is to pass the 256-bit random password generated by the client to the server, then in the process of delivery, the use of the public key is encrypted, so that the 256-bit encryption password is difficult to be cracked on the network.
    2. Symmetric encryption, because the frequent use of asymmetric encryption is very wasteful performance, then SSH is a 256-bit length of password as the next pass the user name password encryption password, its crack difficult, presumably everyone knows, each has 0-9 kinds of changes.
    3. This is safe, I think it is very good, specific use is also easy to understand.

Well, next into the actual operation, I'm using the Java language,

First, you copy the following code snippet.

' Package com.honzh.socket.base.rsa;

Import Java.security.MessageDigest;

Import Javax.crypto.KeyGenerator;
Import Javax.crypto.Mac;
Import Javax.crypto.SecretKey;
Import Javax.crypto.spec.SecretKeySpec;

Import Sun.misc.BASE64Decoder;
Import Sun.misc.BASE64Encoder;

/**
* Basic Cryptographic components
*
* @author Present
* @version 1.0
* @since 1.0
*/
Public abstract class Coder {
public static final String Key_sha = "SHA";
public static final String key_md5 = "MD5";

/** * Mac algorithm can choose the following algorithms * * <pre> * HmacMD5 * HmacSHA1 * HmacSHA256 * HmacSHA384 * HmacSHA512 * </pre> */PUBL IC static final String Key_mac = "HmacMD5";/** * BASE64 decryption * * @param KEY * @return * @throws Exception */public static by Te[] decryptBASE64 (String key) throws Exception {return (new Base64decoder ()). Decodebuffer (key);} /** * BASE64 Encryption * * @param key * @return * @throws Exception */public static String encryptBASE64 (byte[] key) throws Excep tion {return (new Base64encoder ()). Encodebuffer (key);}  /** * MD5 Encryption * * @param data * @return * @throws Exception */public static byte[] EncryptMD5 (byte[) data) throws Exception    {MessageDigest MD5 = messagedigest.getinstance (KEY_MD5);    Md5.update (data); return Md5.digest ();}  /** * SHA Encryption * * @param data * @return * @throws Exception */public static byte[] Encryptsha (byte[) data) throws Exception    {MessageDigest sha = messagedigest.getinstance (Key_sha);    Sha.update (data); return Sha.digest ();} /** * Initialize HMAC key *  * @return * @throws Exception */public static String Initmackey () throws Exception {Keygenerator Keygenerator = Keyg    Enerator.getinstance (KEY_MAC);    Secretkey Secretkey = Keygenerator.generatekey (); Return encryptBASE64 (secretkey.getencoded ());} /** * HMAC Encryption * * @param data * @param key * @return * @throws Exception */public static byte[] Encrypthmac (byte[) data, S    Tring key) throws Exception {Secretkey Secretkey = new Secretkeyspec (decryptBASE64 (key), KEY_MAC);    Mac Mac = Mac.getinstance (Secretkey.getalgorithm ());    Mac.init (Secretkey); return mac.dofinal (data);}

}

Package Com.honzh.socket.base.rsa;

public class Keyresult {
Private String key;
Private byte[] result;
Private String signstr;

public String getKey() {    return key;}public void setKey(String key) {    this.key = key;}public byte[] getResult() {    return result;}public void setResult(byte[] result) {    this.result = result;}/** * @return the signStr */public String getSignStr() {    return signStr;}/** * @param signStr the signStr to set */public void setSignStr(String signStr) {    this.signStr = signStr;}

}

Package Com.honzh.socket.base.rsa;

Import Java.security.Key;
Import Java.security.KeyFactory;
Import Java.security.KeyPair;
Import Java.security.KeyPairGenerator;
Import Java.security.PrivateKey;
Import Java.security.PublicKey;
Import Java.security.Signature;
Import Java.security.interfaces.RSAPrivateKey;
Import Java.security.interfaces.RSAPublicKey;
Import Java.security.spec.PKCS8EncodedKeySpec;
Import Java.security.spec.X509EncodedKeySpec;
Import Java.util.HashMap;
Import Java.util.Map;

Import Javax.crypto.Cipher;

/**
* RSA Secure Encoding Component
*
* @author Present
* @version 1.0
* @since 1.0
*/
Public abstract class Rsacoder extends coder {
public static final String key_algorithm = "RSA";
public static final String signature_algorithm = "Md5withrsa";

private static final String Public_key = "Rsapublickey";p rivate static final String private_key = "Rsaprivatekey";/** * Private Key pair information generates a digital signature * * @param data * encryption * @param privatekey * Private Key * * @return * @throws Exception */publi c static string sign (byte[] data, String privatekey) throws Exception {//Decrypt private key base64 encoded by byte[] Keybytes = DECRYPTB    ASE64 (Privatekey);    Constructs the Pkcs8encodedkeyspec object Pkcs8encodedkeyspec pkcs8keyspec = new Pkcs8encodedkeyspec (keybytes);    Key_algorithm the specified cryptographic algorithm keyfactory keyfactory = keyfactory.getinstance (key_algorithm);    Take the private key object Privatekey Prikey = Keyfactory.generateprivate (Pkcs8keyspec);    Generate digital signatures for information with the private key Signature Signature = Signature.getinstance (signature_algorithm);    Signature.initsign (Prikey);    Signature.update (data); Return encryptBASE64 (Signature.sign ());} /** * Verify the digital signature * * @param data * encryption * @param publickey * Public key * @param sign * Digital signature * * @r Eturn Verify Success Returns TRUE Failure returns false *@throws Exception * */public static Boolean verify (byte[] data, string publickey, String sign) throws Exception {    Decrypt the public key encoded by base64 byte[] Keybytes = decryptBASE64 (PublicKey);    Constructs the X509encodedkeyspec object X509encodedkeyspec keySpec = new X509encodedkeyspec (keybytes);    Key_algorithm the specified cryptographic algorithm keyfactory keyfactory = keyfactory.getinstance (key_algorithm);    Take the public key object PublicKey PubKey = Keyfactory.generatepublic (KeySpec);    Signature Signature = signature.getinstance (signature_algorithm);    Signature.initverify (PubKey);    Signature.update (data); Verify that the signature is normal return signature.verify (decryptBASE64 (sign));} /** * Decrypt <br> * Decrypt with private key * * @param data * @param key * @return * @throws Exception */public static byte[] Decryptbypri    Vatekey (byte[] data, String key) throws Exception {//Decrypt the key byte[] keybytes = decryptBASE64 (key);    Obtain the private key pkcs8encodedkeyspec Pkcs8keyspec = new Pkcs8encodedkeyspec (keybytes); Keyfactory keyfactory = keyfactory.gEtinstance (Key_algorithm);    Key Privatekey = keyfactory.generateprivate (Pkcs8keyspec);    Decrypt the data Cipher Cipher = Cipher.getinstance (Keyfactory.getalgorithm ());    Cipher.init (Cipher.decrypt_mode, Privatekey); return cipher.dofinal (data);} /** * Decrypt <br> * Decrypt with public key * * @param data * @param key * @return * @throws Exception */public static byte[] Decryptbypub    Lickey (byte[] data, String key) throws Exception {//Decrypt the key byte[] keybytes = decryptBASE64 (key);    Get the public key x509encodedkeyspec X509keyspec = new X509encodedkeyspec (keybytes);    Keyfactory keyfactory = keyfactory.getinstance (key_algorithm);    Key PublicKey = Keyfactory.generatepublic (X509keyspec);    Decrypt the data Cipher Cipher = Cipher.getinstance (Keyfactory.getalgorithm ());    Cipher.init (Cipher.decrypt_mode, PublicKey); return cipher.dofinal (data);} /** * Encrypt <br> * Encrypt with public key * * @param data * @param key * @return * @throws Exception */public static byte[] Encryptbypub  Lickey (byte[] data, String key)      Throws Exception {//Decrypt the public key byte[] keybytes = decryptBASE64 (key);    Get the public key x509encodedkeyspec X509keyspec = new X509encodedkeyspec (keybytes);    Keyfactory keyfactory = keyfactory.getinstance (key_algorithm);    Key PublicKey = Keyfactory.generatepublic (X509keyspec);    Encrypt the data Cipher Cipher = Cipher.getinstance (Keyfactory.getalgorithm ());    Cipher.init (Cipher.encrypt_mode, PublicKey); return cipher.dofinal (data);} /** * Encrypt <br> * Encrypt with private key * * @param data * @param key * @return * @throws Exception */public static byte[] Encryptbypri    Vatekey (byte[] data, String key) throws Exception {//Decrypt the key byte[] keybytes = decryptBASE64 (key);    Obtain the private key pkcs8encodedkeyspec Pkcs8keyspec = new Pkcs8encodedkeyspec (keybytes);    Keyfactory keyfactory = keyfactory.getinstance (key_algorithm);    Key Privatekey = keyfactory.generateprivate (Pkcs8keyspec);    Encrypt the data Cipher Cipher = Cipher.getinstance (Keyfactory.getalgorithm ()); Cipher.init (Cipher.encrypt_mode, Privatekey); return cipher.dofinal (data);}  /** * Get the private key * * @param keyMap * @return * @throws Exception */public static String Getprivatekey (map<string, object>    KEYMAP) throws Exception {key key = (key) keymap.get (Private_key); Return encryptBASE64 (key.getencoded ());} /** * Get Public key * * @param keyMap * @return * @throws Exception */public static String Getpublickey (map<string, object>    KEYMAP) throws Exception {key key = (key) keymap.get (Public_key); Return encryptBASE64 (key.getencoded ());} /** * Initialize Key * * @return * @throws Exception */public static map<string, object> Initkey () throws Exception {Key    Pairgenerator Keypairgen = keypairgenerator. getinstance (Key_algorithm);    Keypairgen.initialize (1024);    KeyPair KeyPair = Keypairgen.generatekeypair ();    Public key Rsapublickey PublicKey = (rsapublickey) keypair.getpublic ();    Private key Rsaprivatekey Privatekey = (rsaprivatekey) keypair.getprivate (); Map<string, object> KeyMap = new hashmap<string, object> (2);    Keymap.put (Public_key, PublicKey);    Keymap.put (Private_key, Privatekey); return KEYMAP;}

}

Package com.honzh.socket.util;

Import Javax.crypto.Cipher;
Import Javax.crypto.SecretKey;
Import Javax.crypto.SecretKeyFactory;
Import Javax.crypto.spec.DESKeySpec;
Import Javax.crypto.spec.IvParameterSpec;

public class Cryptutil {
/**
* @Title: Encrypt
* @Description: Encryption
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] Encrypt (byte[] data, byte[] key) throws Exception {
Key = Get8 (key);
Cipher Cipher = cipher.getinstance ("des/cbc/pkcs5padding");
Deskeyspec Deskeyspec = new Deskeyspec (key);
Secretkeyfactory keyfactory = secretkeyfactory.getinstance ("DES");
Secretkey Secretkey = Keyfactory.generatesecret (Deskeyspec);
Ivparameterspec IV = new IVPARAMETERSPEC (key);
Cipher.init (Cipher.encrypt_mode, Secretkey, iv);
return cipher.dofinal (data);
}

/** * @Title: decrypt * @Description: 解密* @param data* @param key* @return* @throws Exception*/public static byte[] decrypt(byte[] data, byte[] key) throws Exception {    key = get8(key);    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");    DESKeySpec desKeySpec = new DESKeySpec(key);    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");    SecretKey secretKey = keyFactory.generateSecret(desKeySpec);    IvParameterSpec iv = new IvParameterSpec(key);    cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);    return cipher.doFinal(data);}private static byte[] get8(byte[] key) {    byte[] key1 = new byte[8];    for (int i = 0; i < 8; i++) {        key1[i] = key[i];    }    return key1;}public static String toHexString(byte[] data) {    String s = "";    for (int i = 0; i < data.length; i++) {        s += Integer.toHexString(data[i] & 0xFF)+"-";    }    return s;}

}
`

Use WebService for communication

WebService, I will no longer do the demo code, to focus on how the SSH principle of the client and server between the request and corresponding.
1. Generate the corresponding public and private keys on the server side

Map<String, Object> keyMap = RSACoder.initKey();                // 产生公钥和私钥                privateKey = RSACoder.getPrivateKey(keyMap);                keyResult.setKey(RSACoder.getPublicKey(keyMap));                logger.info("公钥字符串:" + keyResult.getKey());                logger.info("私钥字符串:" + privateKey);

2. The client obtains the corresponding public key

KeyResult keyResult = (KeyResult) JsonUtil.byteToObject(proxy.request(null, PUBLIC_KEY_RESULT_TYPE),                    KeyResult.class);

3. The client generates a random string and sends it to WEBSERIVCE

String echoStr = getEchoStrByLength(10);            byte[] echoByteParam = RSACoder.encryptByPublicKey(echoStr.getBytes(), keyResult.getKey());            proxy.request(encoder.encode(echoByteParam), ECHOSTR_RESULT_TYPE);

4. Get the password on the server and save it

    // 设置客户端的口令信息                bytenew BASE64Decoder().decodeBuffer(param);                new String(RSACoder.decryptByPrivateKey(paramByte, privateKey));

5. The client encrypts the client request information and then sends it to WebService, first encrypted to a byte array, and then converted to a string

byte[] results = proxy.request(                    encoder.encode(CryptUtil.encrypt(CLIENT_TYPE.getBytes(), echoStr.getBytes())), resultType);            keyResult = (KeyResult) JsonUtil.byteToObject(results, KeyResult.class);

6. After the server has received the corresponding request, the corresponding decryption processing, the request is converted to a byte array, and then decrypted, and finally converted to a string

ExchangeInfo info = ExchangeInfo.dao.getInfoByName(new String(CryptUtil.decrypt(                        new BASE64Decoder().decodeBuffer(param), echoStr.getBytes())));

and return the data through symmetric encryption.

keyResult.setResult(CryptUtil.encrypt(result.getBytes(), echoStr.getBytes()));

7. After the client obtains the data, carries on the corresponding decryption processing

new String(CryptUtil.decrypt(keyResult.getResult(), echoStr.getBytes()));

Summary : The first time to use markdown write so much, is really tired ah, feel not cool enough.

Cryptographic features that enable SSH logins

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.