openstack 云主机密码问题

本贴最后更新于 3260 天前,其中的信息可能已经物是人非

openstack云主机的密码有三种方法:

第一种:通过私钥来解密获取到的密码

         获取当前用户的密码,管理员或者其他用户 。

          前提条件:创建的时候导入了使用秘钥。

创建云主机的时候,使用密钥对创建,密码随机生成,用公钥加密,私钥解密。

私钥在创建秘钥对的时候提供下载,这个是2048位的,未经过PKCS#8编码的私钥文件,在Java里面不能直接使用,需要在Linux上执行# openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt 转换成pkcs8编码格式。

同时通过接口获取到的密码是公钥加密过的,并且经过base64编码过,在进行解码的时候,需要通过BASE64Decoder这个类解码后,再用私钥进行解码。在解码过程中,需要注意:

1、私钥长度是2048,缓存区长度需要设置相应长度;

2、  私钥需要转换pkcs8编码格式;

3、  接口获取的密码需要BASE64Decoder解码。

附测试源代码:

package com.liuxin.openstack;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.security.InvalidKeyException;  
import java.security.KeyFactory;  
import java.security.KeyPair;  
import java.security.KeyPairGenerator;  
import java.security.NoSuchAlgorithmException;  
import java.security.SecureRandom;  
import java.security.interfaces.RSAPrivateKey;  
import java.security.interfaces.RSAPublicKey;  
import java.security.spec.InvalidKeySpecException;  
import java.security.spec.PKCS8EncodedKeySpec;  
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.misc.BASE64Decoder;

public class RSAEncrypt {

private static final String DEFAULT_PUBLIC_KEY=   
    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChDzcjw/rWgFwnxunbKp7/4e8w" + "\r" +  
    "/UmXx2jk6qEEn69t6N2R1i/LmcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRht" + "\r" +  
    "Vx1uOH/2U378fscEESEG8XDqll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNg" + "\r" +  
    "XIlk3gdhnzh+uoEQywIDAQAB" + "\r";  
  
private static final String DEFAULT_PRIVATE_KEY=  
    "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG" + "\r" +  
    "6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4" + "\r" +  
    "1rCLtolpGG1XHW44f/ZTfvx+xwQRIQbxcOqWXQYJ8HX9OMojZqK1VLNc61GzyRiA" + "\r" +  
    "ZTvx/tWYM2BciWTeB2GfOH66gRDLAgMBAAECgYBp4qTvoJKynuT3SbDJY/XwaEtm" + "\r" +  
    "u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j" + "\r" +  
    "DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo" + "\r" +  
    "MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ" + "\r" +  
    "DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM" + "\r" +  
    "6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ" + "\r" +  
    "FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "\r" +  
    "2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "\r" +  
    "TB0TUw8avlaBAXW34/5sI+NUB1hmbgyTK/T/IFcEPXpBWLGO+e3pAkAGWLpnH0Zh" + "\r" +  
    "Fae7oAqkMAd3xCNY6ec180tAe57hZ6kS+SYLKwb4gGzYaCxc22vMtYksXHtUeamo" + "\r" +  
    "1NMLzI2ZfUoX" + "\r";  

/** 
 * 私钥 
 */  
private RSAPrivateKey privateKey;  

/** 
 * 公钥 
 */  
private RSAPublicKey publicKey;  
  
/** 
 * 字节数据转字符串专用集合 
 */  
private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};  
  

/** 
 * 获取私钥 
 * @return 当前的私钥对象 
 */  
public RSAPrivateKey getPrivateKey() {  
    return privateKey;  
}  

/** 
 * 获取公钥 
 * @return 当前的公钥对象 
 */  
public RSAPublicKey getPublicKey() {  
    return publicKey;  
}  

/** 
 * 随机生成密钥对 
 */  
public void genKeyPair(){  
    KeyPairGenerator keyPairGen= null;  
    try {  
        keyPairGen= KeyPairGenerator.getInstance("RSA");  
    } catch (NoSuchAlgorithmException e) {  
        e.printStackTrace();  
    }  
    keyPairGen.initialize(2048, new SecureRandom());  
    KeyPair keyPair= keyPairGen.generateKeyPair();  
    this.privateKey= (RSAPrivateKey) keyPair.getPrivate();  
    this.publicKey= (RSAPublicKey) keyPair.getPublic();  
}  

/** 
 * 从文件中输入流中加载公钥 
 * @param in 公钥输入流 
 * @throws Exception 加载公钥时产生的异常 
 */  
public void loadPublicKey(InputStream in) throws Exception{  
    try {  
        BufferedReader br= new BufferedReader(new InputStreamReader(in));  
        String readLine= null;  
        StringBuilder sb= new StringBuilder();  
        while((readLine= br.readLine())!=null){  
            if(readLine.charAt(0)=='-'){  
                continue;  
            }else{  
                sb.append(readLine);  
                sb.append('\r');  
            }  
        }  
        loadPublicKey(sb.toString());  
    } catch (IOException e) {  
        throw new Exception("公钥数据流读取错误");  
    } catch (NullPointerException e) {  
        throw new Exception("公钥输入流为空");  
    }  
}  


/** 
 * 从字符串中加载公钥 
 * @param publicKeyStr 公钥数据字符串 
 * @throws Exception 加载公钥时产生的异常 
 */  
public void loadPublicKey(String publicKeyStr) throws Exception{  
    try {  
        BASE64Decoder base64Decoder= new BASE64Decoder();  
        byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);  
        KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
        X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);  
        this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);  
    } catch (NoSuchAlgorithmException e) {  
        throw new Exception("无此算法");  
    } catch (InvalidKeySpecException e) {  
        throw new Exception("公钥非法");  
    } catch (IOException e) {  
        throw new Exception("公钥数据内容读取错误");  
    } catch (NullPointerException e) {  
        throw new Exception("公钥数据为空");  
    }  
}  

/** 
 * 从文件中加载私钥 
 * @param keyFileName 私钥文件名 
 * @return 是否成功 
 * @throws Exception  
 */  
public void loadPrivateKey(InputStream in) throws Exception{  
    try {  
        BufferedReader br= new BufferedReader(new InputStreamReader(in));  
        String readLine= null;  
        StringBuilder sb= new StringBuilder();  
        while((readLine= br.readLine())!=null){  
            if(readLine.charAt(0)=='-'){  
                continue;  
            }else{  
                sb.append(readLine);  
                sb.append('\r');  
            }  
        }  
        loadPrivateKey(sb.toString());  
    } catch (IOException e) {  
        throw new Exception("私钥数据读取错误");  
    } catch (NullPointerException e) {  
        throw new Exception("私钥输入流为空");  
    }  
}  

public void loadPrivateKey(String privateKeyStr) throws Exception{  
    try {  
        BASE64Decoder base64Decoder= new BASE64Decoder();  
        byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);  
        PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);  
        KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
        this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
    } catch (NoSuchAlgorithmException e) {  
        throw new Exception("无此算法");  
    } catch (InvalidKeySpecException e) {  
        throw new Exception("私钥非法");  
    } catch (IOException e) {  
        throw new Exception("私钥数据内容读取错误");  
    } catch (NullPointerException e) {  
        throw new Exception("私钥数据为空");  
    }  
}  

/** 
 * 加密过程 
 * @param publicKey 公钥 
 * @param plainTextData 明文数据 
 * @return 
 * @throws Exception 加密过程中的异常信息 
 */  
public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{  
    if(publicKey== null){  
        throw new Exception("加密公钥为空, 请设置");  
    }  
    Cipher cipher= null;  
    try {  
        cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());  
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
        byte[] output= cipher.doFinal(plainTextData);  
        return output;  
    } catch (NoSuchAlgorithmException e) {  
        throw new Exception("无此加密算法");  
    } catch (NoSuchPaddingException e) {  
        e.printStackTrace();  
        return null;  
    }catch (InvalidKeyException e) {  
        throw new Exception("加密公钥非法,请检查");  
    } catch (IllegalBlockSizeException e) {  
        throw new Exception("明文长度非法");  
    } catch (BadPaddingException e) {  
        throw new Exception("明文数据已损坏");  
    }  
}  

/** 
 * 解密过程 
 * @param privateKey 私钥 
 * @param cipherData 密文数据 
 * @return 明文 
 * @throws Exception 解密过程中的异常信息 
 */  
public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{  
    if (privateKey== null){  
        throw new Exception("解密私钥为空, 请设置");  
    }  
    Cipher cipher= null;  
    try {  
        cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());  
        cipher.init(Cipher.DECRYPT_MODE, privateKey);  
        byte[] output= cipher.doFinal(cipherData);  
        return output;  
    } catch (NoSuchAlgorithmException e) {  
        throw new Exception("无此解密算法");  
    } catch (NoSuchPaddingException e) {  
        e.printStackTrace();  
        return null;  
    }catch (InvalidKeyException e) {  
        throw new Exception("解密私钥非法,请检查");  
    } catch (IllegalBlockSizeException e) {  
        throw new Exception("密文长度非法");  
    } catch (BadPaddingException e) {  
        throw new Exception("密文数据已损坏");  
    }         
}  

public static final String PASS="bx8jhAbUOAgMFGXg1jTXWGxYUPn42WlHsu/L16uHWyzOBVoZ+2AhMyIXq2kfw69/xbvjobNcwGMD6t12Q0/4R4EVWGos4Oq0nwwggZ+M+nh30UFUDzibBwGzFpnauToPRJ9iokFipNk9sxvXnyPgPEMiCn2gbBjvelH3J941ZHSVtd6ZDvwzNOvbxDeY86LTjC8aAz+ZpU10MCuE2L0TqGqGU0MqBSyhrq/pF1XrnyNQudPHHbrj+4V/ZNEl4t7z8ge6oizIdvYswrsSsEIFEP5PG4ZVhEKU16JXHMJVixd4kqQDD7vCmx2d4kqyHXynYXnhLN0J4lw8qP/ymEDBXw==";
/** 
 * 字节数据转十六进制字符串 
 * @param data 输入数据 
 * @return 十六进制内容 
 */  
public static String byteArrayToString(byte[] data){  
    StringBuilder stringBuilder= new StringBuilder();  
    for (int i=0; i<data.length; i++){  
        //取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移  
        stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);  
        //取出字节的低四位 作为索引得到相应的十六进制标识符  
        stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);  
        if (i<data.length-1){  
            stringBuilder.append(' ');  
        }  
    }  
    return stringBuilder.toString();  
}  


public static void main(String[] args){  
    RSAEncrypt rsaEncrypt= new RSAEncrypt();  
    //rsaEncrypt.genKeyPair();  

    //加载公钥  
    try {  
        rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);  
        System.out.println("加载公钥成功");  
    } catch (Exception e) {  
        System.err.println(e.getMessage());  
        System.err.println("加载公钥失败");  
    }  

    //加载私钥  
    try {  
    	File file=new File("E://pkcs8_priv.pem");
    	FileInputStream in=new FileInputStream(file);
        rsaEncrypt.loadPrivateKey(in); 
        System.out.println("加载私钥成功");  
    } catch (Exception e) {  
        System.err.println(e.getMessage());  
        System.err.println("加载私钥失败");  
    }  

    //测试字符串  
    String encryptStr= "Test String chaijunkun";  

    try {  
        //加密  

// byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());
BASE64Decoder base64Decoder= new BASE64Decoder();
byte[] cipher=base64Decoder.decodeBuffer(PASS);
//解密 xbRrRZiQ19B1s8QNbH6Z
byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
System.out.println("密文长度:"+ cipher.length);
System.out.println(RSAEncrypt.byteArrayToString(cipher));
System.out.println("明文长度:"+ plainText.length);
System.out.println(RSAEncrypt.byteArrayToString(plainText));
System.out.println(new String(plainText));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}


以上是第一种方式。劣势是不可以在后期通过 API 修改密码。

第二种方式,注入脚本

You can convert the content of your bash script to Base64 encoding and pass it to instance when creating it:
String bashScriptContent = Base64(your-bash-script-content);
ServerCreate sc = Builders.server()
.name("instanceName")
.flavor("3")
.image("6c575333-527c-483b-b449-c496be26d368")//centos
.addAdminPass("mypassword")
.userData(bashScriptContent)
.networks(networks)
.build();
Server server = os.compute().servers().boot(sc);

This works with metadata server AFAIK.

FYI, You can directly inject you ssh key to the created machine. You don't need to pass a default password.

在调用API的时候写入脚本。采用的是openstack 4J

  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 7 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 1 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 373 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 203 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 448 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 416 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    263 引用 • 664 回帖
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 334 关注
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 31 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    89 引用 • 897 回帖 • 1 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 49 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1081 引用 • 3459 回帖 • 231 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 727 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 599 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 330 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 606 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 135 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 368 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    11 引用 • 90 回帖
  • abitmean

    有点意思就行了

    35 关注
  • 导航

    各种网址链接、内容导航。

    38 引用 • 169 回帖
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 16 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 318 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 19 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖