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

📄 secure.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    	data.incrementPosition(length);	
    	
    	for(int i = 0; i < buf.length; i++){
    		buf[i] = (byte) (buf[i] & 0xFF);
    	}
    	
    	ByteArrayInputStream bIn = new ByteArrayInputStream(buf);
    	X509Certificate cert = null;
    	CertificateFactory cf = null;
		try {
			cf = CertificateFactory.getInstance("X.509");
			cert = (X509Certificate)cf.generateCertificate(bIn);
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
    	bIn.reset();
    	return cert;
    }
*/
    public void generateRandom() {
	/*try{
		SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
		random.nextBytes(this.client_random);
    } catch(NoSuchAlgorithmException e){logger.warn("No Such Random Algorithm");}*/
    }

    public void RSAEncrypt(int length) throws RdesktopException {
	byte[] inr = new byte[length];
	//int outlength = 0;
	BigInteger mod = null;
	BigInteger exp = null;
	BigInteger x   = null;

	this.reverse(this.exponent);
	this.reverse(this.modulus);
	System.arraycopy(this.client_random, 0, inr, 0, length);
	this.reverse(inr);

	if ((this.modulus[0] & 0x80) != 0) {
	    byte[] temp = new byte [this.modulus.length+1];
	    System.arraycopy(this.modulus, 0, temp, 1, this.modulus.length);
	    temp[0]=0;
	    mod = new BigInteger(temp);
	} else {
	    mod = new BigInteger(this.modulus);
	}
	if ((this.exponent[0] & 0x80) != 0) {
	    byte[] temp = new byte [this.exponent.length+1];
	    System.arraycopy(this.exponent, 0, temp, 1, this.exponent.length);
	    temp[0]=0;
	    exp = new BigInteger(temp);
	} else {
	    exp = new BigInteger(this.exponent);
	}
	if ((inr[0] & 0x80) != 0) {
	    byte[] temp = new byte [inr.length+1];
	    System.arraycopy(inr, 0, temp, 1, inr.length);
	    temp[0]=0;
	    x = new BigInteger(temp);
	} else {
	    x   = new BigInteger(inr);
	}
	
	BigInteger y = x.modPow(exp, mod);
	this.sec_crypted_random = y.toByteArray();

	if ((this.sec_crypted_random[0] & 0x80) != 0) {
	    throw new RdesktopException("Wrong Sign! Expected positive Integer!");
	}
	
	if (this.sec_crypted_random.length > SEC_MODULUS_SIZE) {
	    logger.warn("sec_crypted_random too big!"); /* FIXME */
	}
	this.reverse(this.sec_crypted_random);

	byte[] temp = new byte[SEC_MODULUS_SIZE];

	if (this.sec_crypted_random.length < SEC_MODULUS_SIZE) {
	    System.arraycopy(this.sec_crypted_random, 0, temp, 0, this.sec_crypted_random.length);
	    for (int i = this.sec_crypted_random.length; i < temp.length; i++) {
		temp[i] = 0;
	    }
	    this.sec_crypted_random = temp;
	    
	}

    }

    

    /**
     * Read in a public key from a provided Secure layer PDU, and store
     * in this.exponent and this.modulus
     * @param data Secure layer PDU containing key data
     * @return True if key successfully read
     * @throws RdesktopException
     */
    public boolean parsePublicKey(RdpPacket_Localised data) throws RdesktopException {
	int magic=0, modulus_length=0;

	magic = data.getLittleEndian32();

	if (magic != SEC_RSA_MAGIC) {
	    throw new RdesktopException("Wrong magic! Expected" + SEC_RSA_MAGIC + "got:" + magic);
	}

	modulus_length = data.getLittleEndian32();
	
	if (modulus_length != SEC_MODULUS_SIZE + SEC_PADDING_SIZE) {
	    throw new RdesktopException("Wrong modulus size! Expected" + SEC_MODULUS_SIZE + "+" + SEC_PADDING_SIZE + "got:" + modulus_length);
	}
	
	data.incrementPosition(8); //unknown modulus bits
	this.exponent = new byte[SEC_EXPONENT_SIZE];
	data.copyToByteArray(this.exponent, 0, data.getPosition(), SEC_EXPONENT_SIZE);	
	data.incrementPosition(SEC_EXPONENT_SIZE);
	this.modulus = new byte[SEC_MODULUS_SIZE];
	data.copyToByteArray(this.modulus, 0, data.getPosition(), SEC_MODULUS_SIZE);
	data.incrementPosition(SEC_MODULUS_SIZE);
	data.incrementPosition(SEC_PADDING_SIZE);

	if (data.getPosition() <= data.getEnd()) {
	    return true;
	} else {
	    return false;
	}
    }
    
    /**
     * Reverse the values in the provided array
     * @param data Array as passed reversed on return
     */
    public void reverse(byte[] data) {
	int i=0, j=0;
	byte temp = 0;

	for(i=0, j=data.length-1; i < j; i++, j--) {
	    temp = data[i];
	    data[i] = data[j];
	    data[j] = temp;
	}
    }
       
     public void reverse(byte[] data, int length) {
	 int i=0, j=0;
	byte temp = 0;
	
	for(i=0, j=length-1; i < j; i++, j--) {
	    temp = data[i];
	    data[i] = data[j];
	    data[j] = temp;
	}
     }

    public byte[] hash48(byte[] in, byte[] salt1, byte[] salt2, int salt)throws CryptoException {
	byte[] shasig = new byte[20];
	byte[] pad = new byte[4];
	byte[] out = new byte[48];
	int i = 0;
	
	for(i=0; i< 3; i++) {
	    for(int j=0; j <=i; j++) {
		pad[j]=(byte)(salt+i);
	    }
	    sha1.engineUpdate(pad, 0, i + 1);
	    sha1.engineUpdate(in, 0, 48);
	    sha1.engineUpdate(salt1, 0, 32);
	    sha1.engineUpdate(salt2, 0, 32);
	    shasig = sha1.engineDigest();
	    sha1.engineReset();

	    md5.engineUpdate(in, 0, 48);
	    md5.engineUpdate(shasig, 0, 20);
	    System.arraycopy(md5.engineDigest(), 0, out, i*16, 16);
	}

	return out;
    }
	
    public byte[] hash16(byte[] in, byte[] salt1, byte[] salt2, int in_position) throws CryptoException {
	
	md5.engineUpdate(in, in_position, 16);
	md5.engineUpdate(salt1, 0, 32);
	md5.engineUpdate(salt2, 0, 32);
	return md5.engineDigest();
    }

    /**
     * Generate a 40-bit key and store in the parameter key.
     * @param key
     */
    public void make40bit(byte[] key) {
	key[0] = (byte)0xd1;
	key[1] = (byte)0x26;
	key[2] = (byte)0x9e;
    }

    /**
     * 
     * @param key
     * @param update_key
     * @return
     * @throws CryptoException
     */
    public byte[] update(byte[] key, byte[] update_key) throws CryptoException {
	byte[] shasig = new byte[20];
	byte[] update = new byte[this.keylength]; // changed from 8 - rdesktop 1.2.0
	byte[] thekey = new byte[key.length];

	sha1.engineReset();
    sha1.engineUpdate(update_key, 0, keylength); 
	sha1.engineUpdate(pad_54, 0, 40);
	sha1.engineUpdate(key,0 , keylength); // changed from 8 - rdesktop 1.2.0
	shasig = sha1.engineDigest();
	sha1.engineReset();

	md5.engineReset();
	md5.engineUpdate(update_key,0 ,keylength); // changed from 8 - rdesktop 1.2.0
	md5.engineUpdate(pad_92, 0, 48);
	md5.engineUpdate(shasig, 0, 20);
	thekey = md5.engineDigest();
	md5.engineReset();

	System.arraycopy(thekey, 0, update, 0, this.keylength);
	rc4_update.engineInitDecrypt(update);
	// added
	thekey = rc4_update.crypt(thekey, 0, this.keylength);

	if( this.keylength == 8) {
	    this.make40bit(thekey);
	}
	
	return thekey;
    }

    /**
     * Write a 32-bit integer value to an array of bytes, length 4
     * @param data Modified by method to be a 4-byte array representing the parameter value
     * @param value Integer value to return as a little-endian 32-bit value
     */
    public void setLittleEndian32(byte[] data, int value) {

	data[3] = (byte)((value >>> 24) & 0xff); 
	data[2] = (byte)((value >>> 16) & 0xff); 
	data[1] = (byte)((value >>> 8) & 0xff); 
	data[0] = (byte)(value & 0xff); 
    }

    /**
     * Receive a Secure layer PDU from the MCS layer
     * 
     * @return Packet representing received Secure PDU
     * @throws RdesktopException
     * @throws IOException
     * @throws CryptoException
     * @throws OrderException
     */
    public RdpPacket_Localised receive() throws RdesktopException, IOException, CryptoException, OrderException {
	int sec_flags=0;
	RdpPacket_Localised buffer=null;
	while(true) {
    	int[] channel = new int[1];
    	buffer=McsLayer.receive(channel);
    	if(buffer==null) return null;
	    buffer.setHeader(RdpPacket_Localised.SECURE_HEADER);
	    if (Constants.encryption || (! this.licenceIssued)) {
	
		sec_flags=buffer.getLittleEndian32();

		if ((sec_flags & SEC_LICENCE_NEG) != 0) {
		   licence.process(buffer);
		    continue;
		}
		if ((sec_flags & SEC_ENCRYPT) != 0) {
		    buffer.incrementPosition(8); //signature
		    byte[] data = new byte[buffer.size() - buffer.getPosition()];
		    buffer.copyToByteArray(data, 0, buffer.getPosition(), data.length);
		    byte[] packet = this.decrypt(data);
		    
		    buffer.copyFromByteArray(packet, 0, buffer.getPosition(), packet.length);

		    //buffer.setStart(buffer.getPosition());
		    //return buffer;
		}
	    }
	    
    		if (channel[0] != MCS.MCS_GLOBAL_CHANNEL)
    		{
    			channels.channel_process(buffer, channel[0]);
    			continue;
    		}
    		
    		buffer.setStart(buffer.getPosition());
    		return buffer;
    	}
    }

    /**
     * Generate encryption keys of applicable size for connection
     * @param rc4_key_size Size of keys to generate (1 if 40-bit encryption, otherwise 128-bit)
     * @throws CryptoException
     */
	public void generate_keys(int rc4_key_size) throws CryptoException {
			byte[] session_key = new byte[48];
			byte[] temp_hash = new byte[48];
			byte[] input = new byte[48];
	
			System.arraycopy(this.client_random, 0, input, 0, 24);
			System.arraycopy(this.server_random, 0, input, 24, 24);

			temp_hash = this.hash48(input, this.client_random, this.server_random, 65);
			session_key = this.hash48(temp_hash, this.client_random, this.server_random, 88);

			System.arraycopy(session_key, 0, this.sec_sign_key, 0, 16); // changed from 8 - rdesktop 1.2.0
	
			this.sec_decrypt_key = this.hash16(session_key, this.client_random, this.server_random, 16);
			this.sec_encrypt_key = this.hash16(session_key, this.client_random, this.server_random, 32);
	
			if (rc4_key_size == 1) {
				logger.info("40 Bit Encryption enabled");
				this.make40bit(this.sec_sign_key);
				this.make40bit(this.sec_decrypt_key);
				this.make40bit(this.sec_encrypt_key);
				this.keylength = 8;
			} else {
				logger.info("128 Bit Encryption enabled");
				this.keylength = 16;
			}
	
			System.arraycopy(this.sec_decrypt_key, 0, this.sec_decrypt_update_key, 0, 16); // changed from 8 - rdesktop 1.2.0
			System.arraycopy(this.sec_encrypt_key, 0, this.sec_encrypt_update_key, 0, 16); // changed from 8 - rdesktop 1.2.0

	
			byte[] key = new byte[this.keylength];
			System.arraycopy(this.sec_encrypt_key, 0, key, 0, this.keylength);
			rc4_enc.engineInitEncrypt(key);
			System.arraycopy(this.sec_decrypt_key, 0, key, 0, this.keylength);
			rc4_dec.engineInitDecrypt(key);
			}

    /**
     * @return MCS user ID
     */
    public int getUserID() {
	return McsLayer.getUserID();
    }
}

⌨️ 快捷键说明

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