Java EC2 Windows-获取管理员密码

Java EC2 Windows-获取管理员密码,java,windows,passwords,amazon-ec2,admin,Java,Windows,Passwords,Amazon Ec2,Admin,目前,我知道的从新创建的EC2 windows实例检索管理员密码的唯一方法是通过AWS管理控制台。这很好,但我需要知道如何通过JavaAPI实现这一点——我似乎找不到任何关于这个主题的东西。此外,获得密码后,如何使用相同的API修改密码?您可以创建一个实例,设置密码,然后将其转换回图像。有效地为您创建的每个实例设置默认密码。这不是更简单吗?看起来您正在寻找API的以下部分:并且EC2 API有一个调用“GetPasswordData”,您可以使用它来检索包含管理员密码的加密数据块。要解密它,您需

目前,我知道的从新创建的EC2 windows实例检索管理员密码的唯一方法是通过AWS管理控制台。这很好,但我需要知道如何通过JavaAPI实现这一点——我似乎找不到任何关于这个主题的东西。此外,获得密码后,如何使用相同的API修改密码?

您可以创建一个实例,设置密码,然后将其转换回图像。有效地为您创建的每个实例设置默认密码。这不是更简单吗?

看起来您正在寻找API的以下部分:并且

EC2 API有一个调用“GetPasswordData”,您可以使用它来检索包含管理员密码的加密数据块。要解密它,您需要两件事:

首先是私钥。这是用于实例化实例的密钥对的私有部分。一个复杂的情况是,Amazon通常使用PEM格式的密钥(“----BEGIN”…),但Java Crypto API需要DER格式的密钥。你可以自己做转换-剥离-----开始和-----结束行,中间的文本块和BASE64解码它。 第二,加密参数。数据使用RSA加密,使用PKCS1填充–因此给JCE的神奇调用是:
Cipher.getInstance(“RSA/NONE/PKCS1Padding”)

下面是一个完整的示例(它依赖于BouncyCastle,但可以修改为使用不同的加密引擎)


ObDisclosure:我最初在一篇博客文章中回答了这个问题,你也可以在这个图片上创建一个带有默认用户名和密码设置的图片。然后用这个图片id启动所有实例。这样你就不需要每次都创建和检索密码了。只需启动你的实例rdp,它用definde credntials启动了实例在图像中。我也在做同样的事情。这对我来说非常有效。

嗯,很有趣的方法-不完全是我需要的。用户将输入一个密码来配置实例(通过自定义界面),因此每次密码都会不同。如果我给它一个默认密码,我仍然会遇到同样的问题(不包括解密步骤),我会将RDP放入实例中,将密码更改为其他密码。我想在不离开代码的情况下配置密码。对于实验性的Windows实例,我发现Spencer概述的方法是必不可少的。如果您必须等待通过web控制台或API获得加密密码,那么EC2上的Windows非常烦人。这通常需要>30分钟,有时甚至长达数小时,但没有明显的原因,而实际图像启动得相当快。不知道为什么会这样,但如果您将管理员密码烘焙到图像中,您可以在一分钟左右的时间内访问它。对于其他读者:如果您的密码无论做什么都无法解密,这可能会有所帮助:
package uk.co.frontiertown;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.GetPasswordDataRequest;
import com.amazonaws.services.ec2.model.GetPasswordDataResult;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.Cipher;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;

public class GetEc2WindowsAdministratorPassword {

    private static final String ACCESS_KEY = "xxxxxxxxxxxxxxxxxxxx";
    private static final String SECRET_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    private static final String PRIVATE_KEY_MATERIAL = "-----BEGIN RSA PRIVATE KEY-----\n" +
        "MIIEowIBAAKCAQEAjdD54kJ88GxkeRc96EQPL4h8c/7V2Q2QY5VUiJ+EblEdcVnADRa12qkohT4I\n" +
        // several more lines of key data
        "srz+xXTvbjIJ6RL/FDqF8lvWEvb8uSC7GeCMHTznkicwUs0WiFax2AcK3xjgtgQXMgoP\n" +
        "-----END RSA PRIVATE KEY-----\n";

    public static void main(String[] args) throws GeneralSecurityException, InterruptedException {
        Security.addProvider(new BouncyCastleProvider());
        String password = getPassword(ACCESS_KEY, SECRET_KEY, "i-XXXXXXXX", PRIVATE_KEY_MATERIAL);
        System.out.println(password);
    }

    private static String getPassword(String accessKey, String secretKey, String instanceId, String privateKeyMaterial) throws GeneralSecurityException, InterruptedException {

        // Convert the private key in PEM format to DER format, which JCE can understand
        privateKeyMaterial = privateKeyMaterial.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
        privateKeyMaterial = privateKeyMaterial.replace("-----END RSA PRIVATE KEY-----", "");
        byte[] der = Base64.decode(privateKeyMaterial);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(der);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        // Get the encrypted password data from EC2
        AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
        AmazonEC2Client client = new AmazonEC2Client(awsCredentials);
        GetPasswordDataRequest getPasswordDataRequest = new GetPasswordDataRequest().withInstanceId(instanceId);
        GetPasswordDataResult getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
        String passwordData = getPasswordDataResult.getPasswordData();
        while (passwordData == null || passwordData.isEmpty()) {
            System.out.println("No password data - probably not generated yet - waiting and retrying");
            Thread.sleep(10000);
            getPasswordDataResult = client.getPasswordData(getPasswordDataRequest);
            passwordData = getPasswordDataResult.getPasswordData();
        }

        // Decrypt the password
        Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] cipherText = Base64.decode(passwordData);
        byte[] plainText = cipher.doFinal(cipherText);
        String password = new String(plainText, Charset.forName("ASCII"));

        return password;
    }
}