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

📄 ssh2keypairfile.java

📁 一个非常好的ssh客户端实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	    } catch (NoSuchAlgorithmException e) {		throw new SSH2FatalException("Invalid cipher in " +					     "SSH2KeyPairFile.writeKeyPair: " + cipher);	    } catch (InvalidKeyException e) {		throw new SSH2FatalException("Invalid key derived in " +					     "SSH2KeyPairFile.writeKeyPair: " + e);	    }	}	SSH2DataBuffer buf = new SSH2DataBuffer(512 + totLen);	buf.writeInt(SSH_PRIVATE_KEY_MAGIC);	buf.writeInt(0); // total length (filled in below)	buf.writeString("dl-modp{sign{dsa-nist-sha1},dh{plain}}");	buf.writeString(cipher);	buf.writeString(toBeEncrypted.getData(), 0, totLen);	totLen = buf.getWPos();	buf.setWPos(4);	buf.writeInt(totLen);	byte[] keyBlob = new byte[totLen];	System.arraycopy(buf.data, 0, keyBlob, 0, totLen);	return keyBlob;    }    public static KeyPair readKeyPair(ASCIIArmour armour, byte[] keyBlob,				      String password)	throws SSH2Exception    {	String procType = armour.getHeaderField(PRV_PROCTYPE);	if(procType != null && password != null) {	    String dekInfo = armour.getHeaderField(PRV_DEKINFO);	    if(dekInfo == null || !dekInfo.startsWith("DES-EDE3-CBC,")) {		throw new SSH2FatalException("Proc type not supported: " +					     procType);	    }	    dekInfo = dekInfo.substring(13);	    BigInteger dekI = new BigInteger(dekInfo, 16);	    byte[] iv = dekI.toByteArray();	    if(iv.length > 8) {		byte[] tmp = iv;		iv = new byte[8];		System.arraycopy(tmp, 1, iv, 0, 8);	    }	    doCipher(Cipher.DECRYPT_MODE, password,		     keyBlob, keyBlob.length, keyBlob, iv);	}	ByteArrayInputStream enc         = new ByteArrayInputStream(keyBlob);	ASN1DER              der         = new ASN1DER();	KeySpec              prvSpec     = null;	KeySpec              pubSpec     = null;	String               keyFactType = null;	String head = armour.getHeaderLine();	if(head.indexOf("DSA") != -1) {	    keyFactType = "DSA";	} else if(head.indexOf("RSA") != -1) {	    keyFactType = "RSA";	}	try {	    if("DSA".equals(keyFactType)) {		PEMDSAPrivate dsa = new PEMDSAPrivate();		der.decode(enc, dsa);		BigInteger p, q, g, x, y;		p = dsa.p.getValue();		q = dsa.q.getValue();		g = dsa.g.getValue();		y = dsa.y.getValue();		x = dsa.x.getValue();		prvSpec = new DSAPrivateKeySpec(x, p, q, g);		pubSpec = new DSAPublicKeySpec(y, p, q, g);	    } else if("RSA".equals(keyFactType)) {		RSAPrivateKey rsa = new RSAPrivateKey();		der.decode(enc, rsa);		BigInteger n, e, d, p, q, pe, qe, u;		n =  rsa.modulus.getValue();		e =  rsa.publicExponent.getValue();		d =  rsa.privateExponent.getValue();		p =  rsa.prime1.getValue();		q =  rsa.prime2.getValue();		pe = rsa.exponent1.getValue();		qe = rsa.exponent2.getValue();		u =  rsa.coefficient.getValue();		prvSpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, pe, qe, u);		pubSpec = new RSAPublicKeySpec(n, e);	    } else {		throw new SSH2FatalException("Unsupported key type: " + keyFactType);	    }	} catch (IOException e) {	    throw new SSH2AccessDeniedException("Invalid password or corrupt key blob");	}	try {	    KeyFactory keyFact = KeyFactory.getInstance(keyFactType);	    return new KeyPair(keyFact.generatePublic(pubSpec),			       keyFact.generatePrivate(prvSpec));	} catch (Exception e) {	    throw new SSH2FatalException("Error in readKeyPair: " + e );	}    }    public static KeyPair readKeyPairSSHCom(byte[] keyBlob, String password)	throws SSH2Exception    {	SSH2DataBuffer buf = new SSH2DataBuffer(keyBlob.length);	buf.writeRaw(keyBlob);	int    magic         = buf.readInt();	int    privateKeyLen = buf.readInt();	String type          = buf.readJavaString();	String cipher        = buf.readJavaString();	int    bufLen        = buf.readInt();	if(type.indexOf("dl-modp") == -1) {	    // !!! TODO: keyformaterror exception?	    throw new SSH2FatalException("Unknown key type '" + type + "'");	}	if(magic != SSH_PRIVATE_KEY_MAGIC) {	    // !!! TODO: keyformaterror exception?	    throw new SSH2FatalException("Invalid magic in private key: " +					 magic);	}	if(!cipher.equals("none")) {	    try {		int    keyLen     = SSH2Preferences.getCipherKeyLen(cipher);		String cipherName = SSH2Preferences.ssh2ToJCECipher(cipher);		byte[] key = expandPasswordToKeySSHCom(password, keyLen);		Cipher decrypt = Cipher.getInstance(cipherName);		decrypt.init(Cipher.DECRYPT_MODE,			     new SecretKeySpec(key, decrypt.getAlgorithm()));		byte[] data   = buf.getData();		int    offset = buf.getRPos();		decrypt.doFinal(data, offset, bufLen, data, offset);	    } catch (NoSuchAlgorithmException e) {		throw new SSH2FatalException("Invalid cipher in " +				     "SSH2KeyPairFile.readKeyPairSSHCom: " +				     cipher);	    } catch (InvalidKeyException e) {		throw new SSH2FatalException("Invalid key derived in " +				     "SSH2KeyPairFile.readKeyPairSSHCom: " + e);	    }	}	int parmLen = buf.readInt();	if(parmLen > buf.getMaxReadSize() || parmLen < 0) {	    throw new SSH2AccessDeniedException("Invalid password or corrupt key blob");	}	int value = buf.readInt();	BigInteger p, q, g, x, y;	if(value == 0) {	    p = buf.readBigIntBits();	    g = buf.readBigIntBits();	    q = buf.readBigIntBits();	    y = buf.readBigIntBits();	    x = buf.readBigIntBits();	} else {	    // !!! TODO: predefined params	    throw new Error("Predefined DSA params not implemented (" +			    value + ") '" + buf.readJavaString() + "'");	}	try {	    KeyFactory keyFact = KeyFactory.getInstance("DSA");	    return new KeyPair(keyFact.generatePublic(					      new DSAPublicKeySpec(y, p, q, g)),			       keyFact.generatePrivate(				      new DSAPrivateKeySpec(x, p, q, g)));	} catch (Exception e) {	    throw new SSH2FatalException(				 "Error in SSH2KeyPairFile.readKeyPair: " + e );	}    }    public void store(String fileName, SecureRandom random, String password)	throws IOException, SSH2FatalException    {	store(fileName, random, password, sshComFormat);    }    public void store(String fileName, SecureRandom random, String password,		      boolean sshComFormat)	throws IOException, SSH2FatalException    {	armour.setBlankHeaderSep(!sshComFormat);	armour.setLineLength(sshComFormat ?			     ASCIIArmour.DEFAULT_LINE_LENGTH : 64);	armour.setHeaderField(PRV_PROCTYPE, null);	armour.setHeaderField(PRV_DEKINFO, null);	armour.setHeaderField(FILE_SUBJECT, null);	armour.setHeaderField(FILE_COMMENT, null);	byte[] keyBlob = null;	if(sshComFormat) {	    if(!(keyPair.getPublic() instanceof DSAPublicKey)) {		throw new SSH2FatalException(	     "Only DSA keys supported when saving in compatibility mode");	    }	    String cipher = ((password != null && password.length() > 0) ?			     "3des-cbc" : "none");	    armour.setHeaderLine(BEGIN_PRV_KEY[TYPE_SSHCOM_DSA]);	    armour.setTailLine(END_PRV_KEY[TYPE_SSHCOM_DSA]);	    comment = "\"" + comment + "\"";	    keyBlob = writeKeyPairSSHCom(password, cipher, keyPair);	} else {	    keyBlob = writeKeyPair(armour, password, random, keyPair);	}	armour.setHeaderField(FILE_SUBJECT, subject);	armour.setHeaderField(FILE_COMMENT, comment);	FileOutputStream out = new FileOutputStream(fileName);	armour.setCanonicalLineEnd(false);	armour.encode(out, keyBlob);	out.close();    }    public void load(String fileName, String password)	throws IOException, SSH2Exception    {	FileInputStream     in  = new java.io.FileInputStream(fileName);	PushbackInputStream pbi = new PushbackInputStream(in);	int c = pbi.read();	if(c != '-') {	    throw new SSH2FatalException("Corrupt or unsupported key file: " +					 fileName);	}	pbi.unread(c);	armour         = new ASCIIArmour("----");	byte[] keyBlob = armour.decode(pbi);	pbi.close();	if(armour.getHeaderLine().indexOf("SSH2") != -1) {	    this.sshComFormat = true;	    this.keyPair      = readKeyPairSSHCom(keyBlob, password);	} else {	    this.keyPair = readKeyPair(armour, keyBlob, password);	}	this.subject = armour.getHeaderField(FILE_SUBJECT);	this.comment = stripQuotes(armour.getHeaderField(FILE_COMMENT));    }    public static byte[] expandPasswordToKey(String password, int keyLen,					     byte[] salt)    {	try {	    MessageDigest md5    = MessageDigest.getInstance("MD5");	    int           digLen = md5.getDigestLength();	    byte[]        mdBuf  = new byte[digLen];	    byte[]        key    = new byte[keyLen];	    int           cnt    = 0;	    while(cnt < keyLen) {		if(cnt > 0) {		    md5.update(mdBuf);		}		md5.update(password.getBytes());		md5.update(salt);		md5.digest(mdBuf, 0, digLen);		int n = ((digLen > (keyLen - cnt)) ? keyLen - cnt : digLen);		System.arraycopy(mdBuf, 0, key, cnt, n);		cnt += n;	    }	    return key;	} catch (Exception e) {	    throw new Error("Error in SSH2KeyPairFile.expandPasswordToKey: " +			    e);	}    }    public static byte[] expandPasswordToKeySSHCom(String password, int keyLen) {	try {	    if(password == null) {		password = "";	    }	    MessageDigest md5    = MessageDigest.getInstance("MD5");	    int           digLen = md5.getDigestLength();	    byte[]        buf    = new byte[((keyLen + digLen) / digLen) *					   digLen];	    int           cnt    = 0;	    while(cnt < keyLen) {		md5.update(password.getBytes());		if(cnt > 0) {		    md5.update(buf, 0, cnt);		}		md5.digest(buf, cnt, digLen);		cnt += digLen;	    }	    byte[] key = new byte[keyLen];	    System.arraycopy(buf, 0, key, 0, keyLen);	    return key;	} catch (Exception e) {	    throw new Error("Error in SSH2KeyPairFile.expandPasswordToKeySSHCom: " + e);	}    }    private static void doCipher(int mode, String password,				 byte[] input, int len, byte[] output,				 byte[] iv)	throws SSH2FatalException    {	byte[] key = expandPasswordToKey(password, 192 / 8, iv);	try {	    Cipher cipher = Cipher.getInstance("3DES/CBC/PKCS5Padding");	    cipher.init(mode, new SecretKeySpec(key, cipher.getAlgorithm()),			new IvParameterSpec(iv));	    cipher.doFinal(input, 0, len, output, 0);	} catch (NoSuchAlgorithmException e) {	    throw new SSH2FatalException("Invalid algorithm in " +					 "SSH2KeyPairFile.doCipher: " + e);	} catch (InvalidKeyException e) {	    throw new SSH2FatalException("Invalid key derived in " +					 "SSH2KeyPairFile.doCipher: " + e);	}    }    private String stripQuotes(String str) throws SSH2FatalException {	if(str != null && str.length() > 0 && str.charAt(0) == '"') {	    if(str.charAt(str.length() - 1) != '"') {		throw new SSH2FatalException("Unbalanced quotes in key file comment");	    }	    str = str.substring(1, str.length() - 1);	}	return str;    }}

⌨️ 快捷键说明

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