⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh2keypairfile.java

📁 一个非常好的ssh客户端实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. *  * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE.  If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************/package com.mindbright.ssh2;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.PushbackInputStream;import java.io.IOException;import java.math.BigInteger;import com.mindbright.jca.security.KeyPair;import com.mindbright.jca.security.PublicKey;import com.mindbright.jca.security.KeyFactory;import com.mindbright.jca.security.MessageDigest;import com.mindbright.jca.security.SecureRandom;import com.mindbright.jca.security.InvalidKeyException;import com.mindbright.jca.security.NoSuchAlgorithmException;import com.mindbright.jca.security.interfaces.DSAParams;import com.mindbright.jca.security.interfaces.DSAPublicKey;import com.mindbright.jca.security.interfaces.RSAPublicKey;import com.mindbright.jca.security.interfaces.DSAPrivateKey;import com.mindbright.jca.security.interfaces.RSAPrivateCrtKey;import com.mindbright.jca.security.spec.KeySpec;import com.mindbright.jca.security.spec.DSAPublicKeySpec;import com.mindbright.jca.security.spec.DSAPrivateKeySpec;import com.mindbright.jca.security.spec.RSAPublicKeySpec;import com.mindbright.jca.security.spec.RSAPrivateCrtKeySpec;import com.mindbright.jce.crypto.Cipher;import com.mindbright.jce.crypto.spec.SecretKeySpec;import com.mindbright.jce.crypto.spec.IvParameterSpec;import com.mindbright.security.pkcs1.RSAPrivateKey;import com.mindbright.asn1.ASN1Object;import com.mindbright.asn1.ASN1OIDRegistry;import com.mindbright.asn1.ASN1Sequence;import com.mindbright.asn1.ASN1Integer;import com.mindbright.asn1.ASN1DER;import com.mindbright.util.ASCIIArmour;import com.mindbright.util.HexDump;/** * This class implements the file formats commonly used for storing key pairs * for public key authentication. It can handle both OpenSSH's PEM file format * aswell as SSH Communications proprietary format for DSA keys. When * importing/exporting use the appropriate constructor and the load/store * methods. Note that this class can also be used to convert key pair files * between the formats. * * @see SSH2PublicKeyFile */public class SSH2KeyPairFile {    private final static int TYPE_PEM_DSA    = 0;    private final static int TYPE_PEM_RSA    = 1;    private final static int TYPE_SSHCOM_DSA = 2;    public final static String[] BEGIN_PRV_KEY = {	"-----BEGIN DSA PRIVATE KEY-----",	"-----BEGIN RSA PRIVATE KEY-----",	"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"    };    public final static String[] END_PRV_KEY   = {	"-----END DSA PRIVATE KEY-----",	"-----END RSA PRIVATE KEY-----",	"---- END SSH2 ENCRYPTED PRIVATE KEY ----"    };    public final static int SSH_PRIVATE_KEY_MAGIC = 0x3f6ff9eb;    public final static String PRV_PROCTYPE = "Proc-Type";    public final static String PRV_DEKINFO  = "DEK-Info";    public final static String FILE_SUBJECT = "Subject";    public final static String FILE_COMMENT = "Comment";    private KeyPair       keyPair;    private ASCIIArmour   armour;    private String        subject;    private String        comment;    private boolean       sshComFormat;    static {	ASN1OIDRegistry.addModule("com.mindbright.security.pkcs1");    }    /**     * Handles PEM encoding of a DSA key. From OpenSSL doc for dsa.     * <p>     * <pre>     * PEMDSAPrivate ::= SEQUENCE {     *   version  Version,     *   p        INTEGER,     *   q        INTEGER,     *   g        INTEGER,     *   y        INTEGER,     *   x        INTEGER     * }     *     * Version ::= INTEGER { openssl(0) }     * </pre>     * (OpenSSL currently hardcodes version to 0)     */    public static final class PEMDSAPrivate extends ASN1Sequence {	public ASN1Integer version;	public ASN1Integer p;	public ASN1Integer q;	public ASN1Integer g;	public ASN1Integer y;	public ASN1Integer x;	public PEMDSAPrivate() {	    version = new ASN1Integer();	    p       = new ASN1Integer();	    q       = new ASN1Integer();	    g       = new ASN1Integer();	    y       = new ASN1Integer();	    x       = new ASN1Integer();	    addComponent(version);	    addComponent(p);	    addComponent(q);	    addComponent(g);	    addComponent(y);	    addComponent(x);	}	public PEMDSAPrivate(int version,			     BigInteger p, BigInteger q, BigInteger g,			     BigInteger y, BigInteger x) {	    this();	    this.version.setValue(version);	    this.p.setValue(p);	    this.q.setValue(q);	    this.g.setValue(g);	    this.y.setValue(y);	    this.x.setValue(x);	}    }    /**     * This is the constructor used for storing a key pair.     *     * @param keyPair the key pair to store     * @param subject the subject name of the key owner     * @param comment a comment to accompany the key     */    public SSH2KeyPairFile(KeyPair keyPair, String subject, String comment) {	this.keyPair = keyPair;	this.armour  = new ASCIIArmour("----");	this.subject = subject;	this.comment = comment;    }    /**     * This is the constructor used for loading a key pair.     */    public SSH2KeyPairFile() {	this(null, null, null);    }    public KeyPair getKeyPair() {	return keyPair;    }    public String getSubject() {	return subject;    }    public void setSubject(String subject) {	this.subject = subject;     }    public String getComment() {	return comment;    }    public void setComment(String comment) {	this.comment = comment;    }    public ASCIIArmour getArmour() {	return armour;    }    public boolean isSSHComFormat() {	return sshComFormat;    }    public String getAlgorithmName() {	PublicKey publicKey = keyPair.getPublic();	String    alg       = null;	if(publicKey instanceof DSAPublicKey) {	    alg = "ssh-dss";	} else if(publicKey instanceof RSAPublicKey) {	    alg = "ssh-rsa";	}	return alg;    }    public int getBitLength() {	PublicKey publicKey = keyPair.getPublic();	if(publicKey instanceof DSAPublicKey) {	    return ((DSAPublicKey)publicKey).getParams().getP().bitLength();	} else {	    return ((RSAPublicKey)publicKey).getModulus().bitLength();	}    }    public static byte[] writeKeyPair(ASCIIArmour armour, String password,				      SecureRandom random,				      KeyPair keyPair)	throws SSH2FatalException    {	ASN1Object pem;	PublicKey  publicKey = keyPair.getPublic();	int        headType;	if(publicKey instanceof DSAPublicKey) {	    DSAPublicKey  pubKey = (DSAPublicKey)keyPair.getPublic();	    DSAPrivateKey prvKey = (DSAPrivateKey)keyPair.getPrivate();	    DSAParams     params = pubKey.getParams();	    PEMDSAPrivate dsa = new PEMDSAPrivate(0,						  params.getP(),						  params.getQ(),						  params.getG(),						  pubKey.getY(),						  prvKey.getX());	    pem = dsa;	    headType = TYPE_PEM_DSA;	} else if(publicKey instanceof RSAPublicKey) {	    RSAPublicKey     pubKey = (RSAPublicKey)keyPair.getPublic();	    RSAPrivateCrtKey prvKey = (RSAPrivateCrtKey)keyPair.getPrivate();	    RSAPrivateKey rsa = new RSAPrivateKey(0,						  pubKey.getModulus(),						  pubKey.getPublicExponent(),						  prvKey.getPrivateExponent(),						  prvKey.getPrimeP(),						  prvKey.getPrimeQ(),						  prvKey.getCrtCoefficient());	    pem = rsa;	    headType = TYPE_PEM_RSA;	} else {	    throw new SSH2FatalException("Unsupported key type: " + publicKey);	}	armour.setHeaderLine(BEGIN_PRV_KEY[headType]);	armour.setTailLine(END_PRV_KEY[headType]);	ByteArrayOutputStream enc = new ByteArrayOutputStream(128);	ASN1DER               der = new ASN1DER();	try {	    der.encode(enc, pem);	} catch (IOException e) {	    throw new SSH2FatalException("Error while DER encoding");	}	byte[] keyBlob = enc.toByteArray();	if(password != null && password.length() > 0) {	    byte[] iv = new byte[8];	    byte[] key;	    random.setSeed(keyBlob);	    for(int i = 0; i < 8; i++) {		byte[] r = new byte[1];		do {		    random.nextBytes(r);		    iv[i] = r[0];		} while(iv[i] == 0x00);	    }	    key = expandPasswordToKey(password, 192 / 8, iv);	    armour.setHeaderField(PRV_PROCTYPE, "4,ENCRYPTED");	    armour.setHeaderField(PRV_DEKINFO, "DES-EDE3-CBC," +				  HexDump.toString(iv).toUpperCase());	    int    encLen = (8 - (keyBlob.length % 8)) + keyBlob.length;	    byte[] encBuf = new byte[encLen];	    doCipher(Cipher.ENCRYPT_MODE, password,		     keyBlob, keyBlob.length, encBuf, iv);	    keyBlob = encBuf;	}	return keyBlob;    }    public static byte[] writeKeyPairSSHCom(String password,					    String cipher, KeyPair keyPair)	throws SSH2FatalException    {	SSH2DataBuffer toBeEncrypted = new SSH2DataBuffer(8192);	int            totLen        = 0;	DSAPublicKey  pubKey = (DSAPublicKey)keyPair.getPublic();	DSAPrivateKey prvKey = (DSAPrivateKey)keyPair.getPrivate();	DSAParams     params = pubKey.getParams();	if(!(pubKey instanceof DSAPublicKey)) {	    throw new SSH2FatalException("Unsupported key type: " + pubKey);	}	toBeEncrypted.writeInt(0); // unenc length (filled in below)	toBeEncrypted.writeInt(0); // type 0 is explicit params (as opposed to predefined)	toBeEncrypted.writeBigIntBits(params.getP());	toBeEncrypted.writeBigIntBits(params.getG());	toBeEncrypted.writeBigIntBits(params.getQ());	toBeEncrypted.writeBigIntBits(pubKey.getY());	toBeEncrypted.writeBigIntBits(prvKey.getX());	totLen = toBeEncrypted.getWPos();	toBeEncrypted.setWPos(0);	toBeEncrypted.writeInt(totLen - 4);	if(!cipher.equals("none")) {	    try {		int    keyLen     = SSH2Preferences.getCipherKeyLen(cipher);		String cipherName = SSH2Preferences.ssh2ToJCECipher(cipher);		byte[] key = expandPasswordToKeySSHCom(password, keyLen);		Cipher encrypt = Cipher.getInstance(cipherName);		encrypt.init(Cipher.ENCRYPT_MODE,			     new SecretKeySpec(key, encrypt.getAlgorithm()));		byte[] data = toBeEncrypted.getData();		int    bs   = encrypt.getBlockSize();		totLen += (bs - (totLen % bs)) % bs;		totLen = encrypt.doFinal(data, 0, totLen, data, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -