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

📄 secure.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	buffer.incrementPosition(SEC_MODULUS_SIZE);
	buffer.incrementPosition(SEC_PADDING_SIZE);
	buffer.markEnd();
	this.send(buffer, flags);
	
    }

    public void processCryptInfo(RdpPacket_Localised data) throws RdesktopException, CryptoException {
	int rc4_key_size=0;
	    
	rc4_key_size = this.parseCryptInfo(data);
	if (rc4_key_size == 0) {
	    return;
	}
	
	//this.client_random = this.generateRandom(SEC_RANDOM_SIZE);
	logger.debug("readCert = " + readCert);
	if (readCert)
	{			/* Which means we should use 
				   RDP5-style encryption */
		
		
		// *** reverse the client random
		//this.reverse(this.client_random);
		
		// *** load the server public key into the stored data for encryption
		/* this.exponent = this.server_public_key.getPublicExponent().toByteArray();
		this.modulus = this.server_public_key.getModulus().toByteArray();
		
		System.out.println("Exponent: " + server_public_key.getPublicExponent());
		System.out.println("Modulus: " + server_public_key.getModulus());
		*/
		
		// *** perform encryption
		//this.sec_crypted_random = RSA_public_encrypt(this.client_random, this.server_public_key);
		//this.RSAEncrypt(SEC_RANDOM_SIZE);
		
		//this.RSAEncrypt(SEC_RANDOM_SIZE);
		
		// *** reverse the random data back
		//this.reverse(this.sec_crypted_random);

	}
	else{
		this.generateRandom();
		this.RSAEncrypt(SEC_RANDOM_SIZE);
	}
	this.generate_keys(rc4_key_size);
    }

    /**
     * Intialise a packet at the Secure layer
     * @param flags Encryption flags
     * @param length Length of packet
     * @return Intialised packet
     * @throws RdesktopException
     */
    public RdpPacket_Localised init(int flags, int length) throws RdesktopException {
	int headerlength=0;
	RdpPacket_Localised buffer;
 
	if (!this.licenceIssued) 
	    headerlength = ((flags & SEC_ENCRYPT)!=0) ? 12 : 4;
	else 
	     headerlength = ((flags & SEC_ENCRYPT)!=0) ? 12 : 0;
	
	buffer=McsLayer.init(length+headerlength);
	buffer.pushLayer(RdpPacket_Localised.SECURE_HEADER,headerlength);
	//buffer.setHeader(RdpPacket_Localised.SECURE_HEADER);
	//buffer.incrementPosition(headerlength);
	//buffer.setStart(buffer.getPosition());
	return buffer;
    }

    /**
     * Send secure data on the global channel
     * @param sec_data Data to send
     * @param flags Encryption flags
     * @throws RdesktopException
     * @throws IOException
     * @throws CryptoException
     */
	public void send(RdpPacket_Localised sec_data, int flags) throws RdesktopException, IOException, CryptoException {
		send_to_channel(sec_data,flags,MCS.MCS_GLOBAL_CHANNEL);
	}
    
    /**
     * Prepare data as a Secure PDU and pass down to the MCS layer
     * @param sec_data Data to send
     * @param flags Encryption flags
     * @param channel Channel over which to send data
     * @throws RdesktopException
     * @throws IOException
     * @throws CryptoException
     */
    public void send_to_channel(RdpPacket_Localised sec_data, int flags, int channel) throws RdesktopException, IOException, CryptoException {
	int datalength=0;
	byte[] signature = null;
	byte[] data;
	byte[] buffer;

	sec_data.setPosition(sec_data.getHeader(RdpPacket_Localised.SECURE_HEADER));
	
	if (this.licenceIssued == false || (flags & SEC_ENCRYPT) !=0) {
	    sec_data.setLittleEndian32(flags);
	}
	if ((flags & SEC_ENCRYPT) !=0) {
	    flags &= ~SEC_ENCRYPT;
	    datalength = sec_data.getEnd() - sec_data.getPosition() - 8;
	    data = new byte[datalength];
	    buffer = null;
	    sec_data.copyToByteArray(data, 0, sec_data.getPosition()+8, datalength); 
	    signature = this.sign(this.sec_sign_key, 8, this.keylength, data, datalength);
	   
	    buffer = this.encrypt(data, datalength);
	    
	    sec_data.copyFromByteArray(signature, 0, sec_data.getPosition(), 8);
	    sec_data.copyFromByteArray(buffer, 0, sec_data.getPosition()+8, datalength);
	   
	}
	//McsLayer.send(sec_data);
    McsLayer.send_to_channel(sec_data,channel);
    }

    /**
     * Generate MD5 signature
     * @param session_key Key with which to sign data
     * @param length Length of signature
     * @param keylen Length of key
     * @param data Data to sign
     * @param datalength Length of data to sign
     * @return Signature for data
     * @throws CryptoException
     */
    public byte[] sign(byte[] session_key, int length, int keylen, byte[] data, int datalength) throws CryptoException {
	byte[] shasig = new byte[20];
	byte[] md5sig = new byte[16];
	byte[] lenhdr = new byte[4];
	byte[] signature = new byte[length];

	this.setLittleEndian32(lenhdr, datalength);
	
	sha1.engineReset();
	sha1.engineUpdate(session_key, 0, keylen/*length*/);
	sha1.engineUpdate(pad_54, 0, 40);
	sha1.engineUpdate(lenhdr, 0, 4);
	sha1.engineUpdate(data, 0, datalength);
	shasig = sha1.engineDigest();
	sha1.engineReset();

	md5.engineReset();
	md5.engineUpdate(session_key, 0, keylen/*length*/);
	md5.engineUpdate(pad_92, 0, 48);
	md5.engineUpdate(shasig, 0, 20);
	md5sig = md5.engineDigest();
	md5.engineReset();

	System.arraycopy(md5sig, 0, signature, 0, length);
	return signature;
    }

    /**
     * Encrypt specified number of bytes from provided data using RC4 algorithm
     * @param data Data to encrypt
     * @param length Number of bytes to encrypt (from start of array)
     * @return Encrypted data
     * @throws CryptoException
     */
    public byte[] encrypt(byte[] data, int length) throws CryptoException {
	byte[] buffer = null;
	if (this.enc_count==4096) {
	    sec_encrypt_key = this.update(this.sec_encrypt_key, this.sec_encrypt_update_key);
	    byte[] key = new byte[this.keylength];
	    System.arraycopy(this.sec_encrypt_key, 0, key, 0, this.keylength);
	    this.rc4_enc.engineInitEncrypt(key);
//		logger.debug("Packet enc_count="+enc_count);
		 this.enc_count=0;
	}
	//this.rc4.engineInitEncrypt(this.rc4_encrypt_key);
	buffer = this.rc4_enc.crypt(data, 0, length);
	this.enc_count++;
	return buffer;
    }
    
    /**
     * Encrypt provided data using the RC4 algorithm
     * @param data Data to encrypt
     * @return Encrypted data
     * @throws CryptoException
     */
    public byte[] encrypt(byte[] data) throws CryptoException {
	byte[] buffer = null;
	if (this.enc_count==4096) {
	    sec_encrypt_key = this.update(this.sec_encrypt_key, this.sec_encrypt_update_key);
	    byte[] key = new byte[this.keylength];
	    System.arraycopy(this.sec_encrypt_key, 0, key, 0, this.keylength);
	    this.rc4_enc.engineInitEncrypt(key);
	//	logger.debug("Packet enc_count="+enc_count);
		this.enc_count=0;
	}
//	this.rc4.engineInitEncrypt(this.rc4_encrypt_key);
	
	buffer = this.rc4_enc.crypt(data);
	this.enc_count++;
	return buffer;
    }

    /**
     * Decrypt specified number of bytes from provided data using RC4 algorithm
     * @param data Data to decrypt
     * @param length Number of bytes to decrypt (from start of array)
     * @return Decrypted data
     * @throws CryptoException
     */
    public byte[] decrypt(byte[] data, int length) throws CryptoException {
	byte[] buffer = null;
	if (this.dec_count==4096) {
	    sec_decrypt_key = this.update(this.sec_decrypt_key, this.sec_decrypt_update_key);
	    byte[] key = new byte[this.keylength];
	    System.arraycopy(this.sec_decrypt_key, 0, key, 0, this.keylength);
	    this.rc4_dec.engineInitDecrypt(key);
//		logger.debug("Packet dec_count="+dec_count);
		this.dec_count=0;
	}
	//this.rc4.engineInitDecrypt(this.rc4_decrypt_key);
	buffer = this.rc4_dec.crypt(data, 0, length);
	this.dec_count++;
	return buffer;
    }
    
    /**
     * Decrypt provided data using RC4 algorithm
     * @param data Data to decrypt
     * @return Decrypted data
     * @throws CryptoException
     */
    public byte[] decrypt(byte[] data) throws CryptoException {
	byte[] buffer = null;
	if (this.dec_count==4096) {
	    sec_decrypt_key = this.update(this.sec_decrypt_key, this.sec_decrypt_update_key);
	    byte[] key = new byte[this.keylength];
	    System.arraycopy(this.sec_decrypt_key, 0, key, 0, this.keylength);
	    this.rc4_dec.engineInitDecrypt(key);
//		logger.debug("Packet dec_count="+dec_count);
		this.dec_count=0;
	}
	//this.rc4.engineInitDecrypt(this.rc4_decrypt_key);
	
	buffer = this.rc4_dec.crypt(data);
	this.dec_count++;
	return buffer;
    }
    
    /**
     * Read encryption information from a Secure layer PDU, obtaining and storing
     * level of encryption and any keys received
     * @param data Packet to read encryption information from
     * @return Size of RC4 key
     * @throws RdesktopException
     */
    public int parseCryptInfo(RdpPacket_Localised data) throws RdesktopException {
	logger.debug("Secure.parseCryptInfo");
	int encryption_level=0, random_length=0, RSA_info_length=0;
	int tag=0, length=0;
	int next_tag=0, end=0; 
	int rc4_key_size=0;

	rc4_key_size = data.getLittleEndian32(); // 1 = 40-Bit 2 = 128 Bit
	encryption_level = data.getLittleEndian32(); // 1 = low, 2 = medium, 3 = high
	if (encryption_level==0) { // no encryption
	    return 0;
	}
	random_length = data.getLittleEndian32();
	RSA_info_length = data.getLittleEndian32();

	if ( random_length != SEC_RANDOM_SIZE) {
	    throw new RdesktopException("Wrong Size of Random! Got" + random_length + "expected" + SEC_RANDOM_SIZE);
	}
	this.server_random = new byte[random_length];
	data.copyToByteArray(this.server_random, 0, data.getPosition(), random_length);
	data.incrementPosition(random_length);

	end = data.getPosition() + RSA_info_length;

	if (end > data.getEnd()) {
	   logger.debug("Reached end of crypt info prematurely ");
	    return 0;
	}

	//data.incrementPosition(12); // unknown bytes
	int flags = data.getLittleEndian32(); // in_uint32_le(s, flags);	// 1 = RDP4-style, 0x80000002 = X.509
	logger.debug("Flags = 0x" + Integer.toHexString(flags));
	if ((flags & 1) != 0)
	{
		logger.debug(("We're going for the RDP4-style encryption"));
		data.incrementPosition(8); //in_uint8s(s, 8);	// unknown

	while (data.getPosition() < data.getEnd()) {
	    tag=data.getLittleEndian16();
	    length=data.getLittleEndian16();

	    next_tag = data.getPosition() + length;

	    switch (tag) {

	    case (Secure.SEC_TAG_PUBKEY):
		
		if (!parsePublicKey(data)) {
		    return 0;
		}
		
		break;
	    case (Secure.SEC_TAG_KEYSIG):
		// Microsoft issued a key but we don't care
		break;

	    default:
		throw new RdesktopException("Unimplemented decrypt tag "+tag);
	    }
	    data.setPosition(next_tag);
	}

	if (data.getPosition() == data.getEnd()) {
	    return rc4_key_size;
	} else {
	    logger.warn("End not reached!");
	    return 0;
	}
	
	}else{
		//data.incrementPosition(4); // number of certificates
		int num_certs = data.getLittleEndian32();
		
		int cacert_len = data.getLittleEndian32();
		data.incrementPosition(cacert_len);
		int cert_len = data.getLittleEndian32();
		data.incrementPosition(cert_len);
		
		readCert = true;
		
		return rc4_key_size;
	}
	
	
    }
    /*
    public X509Certificate readCert(int length, RdpPacket_Localised data){  	
    	byte[] buf = new byte[length];
    	
    	data.copyToByteArray(buf,0,data.getPosition(),buf.length);

⌨️ 快捷键说明

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