openstack 云主机密码问题

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

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 引用 • 3 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 倾城之链
    23 引用 • 66 回帖 • 158 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    1 引用 • 1 回帖 • 23 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    494 引用 • 928 回帖
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 109 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖 • 4 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 595 回帖 • 1 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1235 回帖 • 414 关注
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 157 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    31 引用 • 96 回帖
  • Log4j

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

    20 引用 • 18 回帖 • 32 关注
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 367 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    345 引用 • 742 回帖
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 28 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 544 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 543 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖 • 1 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 637 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 175 关注
  • 黑曜石

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

    A second brain, for you, forever.

    21 引用 • 204 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖